kash-shell 0.3.16__py3-none-any.whl → 0.3.18__py3-none-any.whl
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.
- kash/actions/core/minify_html.py +41 -0
- kash/commands/base/files_command.py +2 -2
- kash/commands/base/show_command.py +11 -1
- kash/config/colors.py +20 -8
- kash/docs/markdown/topics/a1_what_is_kash.md +52 -23
- kash/docs/markdown/topics/a2_installation.md +17 -30
- kash/docs/markdown/topics/a3_getting_started.md +5 -19
- kash/exec/action_exec.py +1 -1
- kash/exec/fetch_url_metadata.py +9 -0
- kash/exec/precondition_registry.py +3 -3
- kash/file_storage/file_store.py +18 -1
- kash/llm_utils/llm_features.py +5 -1
- kash/llm_utils/llms.py +18 -8
- kash/media_base/media_cache.py +48 -24
- kash/media_base/media_services.py +63 -14
- kash/media_base/services/local_file_media.py +9 -1
- kash/model/actions_model.py +2 -2
- kash/model/items_model.py +4 -5
- kash/model/media_model.py +9 -1
- kash/model/params_model.py +9 -3
- kash/utils/common/function_inspect.py +97 -1
- kash/utils/common/testing.py +58 -0
- kash/utils/common/url_slice.py +329 -0
- kash/utils/file_utils/file_formats.py +1 -1
- kash/utils/text_handling/markdown_utils.py +424 -16
- kash/web_gen/templates/base_styles.css.jinja +204 -25
- kash/web_gen/templates/base_webpage.html.jinja +48 -26
- kash/web_gen/templates/components/toc_scripts.js.jinja +319 -0
- kash/web_gen/templates/components/toc_styles.css.jinja +284 -0
- kash/web_gen/templates/components/tooltip_scripts.js.jinja +730 -0
- kash/web_gen/templates/components/tooltip_styles.css.jinja +482 -0
- kash/web_gen/templates/content_styles.css.jinja +13 -8
- kash/web_gen/templates/simple_webpage.html.jinja +59 -21
- kash/web_gen/templates/tabbed_webpage.html.jinja +4 -2
- kash/workspaces/workspaces.py +10 -1
- {kash_shell-0.3.16.dist-info → kash_shell-0.3.18.dist-info}/METADATA +75 -72
- {kash_shell-0.3.16.dist-info → kash_shell-0.3.18.dist-info}/RECORD +40 -33
- {kash_shell-0.3.16.dist-info → kash_shell-0.3.18.dist-info}/WHEEL +0 -0
- {kash_shell-0.3.16.dist-info → kash_shell-0.3.18.dist-info}/entry_points.txt +0 -0
- {kash_shell-0.3.16.dist-info → kash_shell-0.3.18.dist-info}/licenses/LICENSE +0 -0
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
--font-sans: "Source Sans 3 Variable", sans-serif, "Hack Nerd Font";
|
|
6
6
|
--font-serif: "PT Serif", serif, "Hack Nerd Font";
|
|
7
7
|
/* Source Sans 3 Variable better at these weights. */
|
|
8
|
-
--font-weight-sans-
|
|
8
|
+
--font-weight-sans-medium: 565;
|
|
9
|
+
--font-weight-sans-bold: 650;
|
|
9
10
|
--font-mono: "Hack Nerd Font", "Menlo", "DejaVu Sans Mono", Consolas, "Lucida Console", monospace;
|
|
10
11
|
|
|
11
12
|
--font-size-large: 1.2rem;
|
|
@@ -68,6 +69,14 @@
|
|
|
68
69
|
}
|
|
69
70
|
{% endblock scrollbar_styles %}
|
|
70
71
|
|
|
72
|
+
{% block html_styles %}
|
|
73
|
+
/* Prevent horizontal overflow at the root level */
|
|
74
|
+
html {
|
|
75
|
+
overflow-x: hidden;
|
|
76
|
+
width: 100%;
|
|
77
|
+
}
|
|
78
|
+
{% endblock html_styles %}
|
|
79
|
+
|
|
71
80
|
{% block body_styles %}
|
|
72
81
|
body {
|
|
73
82
|
font-family: var(--font-serif);
|
|
@@ -109,7 +118,9 @@ a:hover {
|
|
|
109
118
|
h1,
|
|
110
119
|
h2,
|
|
111
120
|
h3,
|
|
112
|
-
h4
|
|
121
|
+
h4,
|
|
122
|
+
h5,
|
|
123
|
+
h6 {
|
|
113
124
|
line-height: 1.2;
|
|
114
125
|
}
|
|
115
126
|
|
|
@@ -120,7 +131,7 @@ h1 {
|
|
|
120
131
|
}
|
|
121
132
|
|
|
122
133
|
h2 {
|
|
123
|
-
font-size: 1.
|
|
134
|
+
font-size: 1.42rem;
|
|
124
135
|
margin-top: 2rem;
|
|
125
136
|
margin-bottom: 1rem;
|
|
126
137
|
}
|
|
@@ -129,17 +140,32 @@ h1 + h2 {
|
|
|
129
140
|
margin-top: 2rem;
|
|
130
141
|
}
|
|
131
142
|
|
|
143
|
+
h2 + h3 {
|
|
144
|
+
margin-top: 1.1rem;
|
|
145
|
+
}
|
|
146
|
+
|
|
132
147
|
h3 {
|
|
133
|
-
font-size: 1.
|
|
134
|
-
margin-top: 1.
|
|
135
|
-
margin-bottom: 0.
|
|
148
|
+
font-size: 1.18rem;
|
|
149
|
+
margin-top: 1.4rem;
|
|
150
|
+
margin-bottom: 0.7rem;
|
|
136
151
|
}
|
|
137
152
|
|
|
138
153
|
h4 {
|
|
154
|
+
font-size: 1.1rem;
|
|
139
155
|
margin-top: 1rem;
|
|
140
156
|
margin-bottom: 0.7rem;
|
|
141
157
|
}
|
|
142
158
|
|
|
159
|
+
h5, h6 {
|
|
160
|
+
font-size: 1rem;
|
|
161
|
+
margin-top: 0.7rem;
|
|
162
|
+
margin-bottom: 0.5rem;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
h4+p, h5+p, h6+p {
|
|
166
|
+
margin-top: 0;
|
|
167
|
+
}
|
|
168
|
+
|
|
143
169
|
ul {
|
|
144
170
|
list-style-type: none;
|
|
145
171
|
margin-left: 1.8rem;
|
|
@@ -187,20 +213,34 @@ code {
|
|
|
187
213
|
font-family: var(--font-mono);
|
|
188
214
|
font-size: var(--font-size-mono);
|
|
189
215
|
letter-spacing: -0.025em;
|
|
216
|
+
|
|
190
217
|
transition: color 0.4s ease-in-out;
|
|
191
218
|
}
|
|
219
|
+
/* For code inside pre we style the pre tag */
|
|
220
|
+
code:not(pre code) {
|
|
221
|
+
background-color: var(--color-bg-alt);
|
|
222
|
+
border-radius: 3px;
|
|
223
|
+
border: 1px solid var(--color-hint-gentle);
|
|
224
|
+
padding: 0.25em 0.2em 0.1em 0.2em;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* Code block wrapper for positioning copy button */
|
|
228
|
+
.code-block-wrapper {
|
|
229
|
+
position: relative;
|
|
230
|
+
}
|
|
192
231
|
|
|
193
232
|
/* Code blocks (pre + code) */
|
|
194
233
|
pre {
|
|
195
234
|
font-family: var(--font-mono);
|
|
196
235
|
font-size: var(--font-size-mono);
|
|
197
236
|
letter-spacing: -0.025em;
|
|
237
|
+
|
|
198
238
|
background-color: var(--color-bg-alt);
|
|
199
|
-
border-radius:
|
|
200
|
-
border: 1px
|
|
201
|
-
padding: 0.
|
|
239
|
+
border-radius: 3px;
|
|
240
|
+
border: 1px solid var(--color-hint-gentle);
|
|
241
|
+
padding: 0.25rem 0.2rem 0.1rem 0.2rem;
|
|
202
242
|
overflow-x: auto; /* Enable horizontal scrolling */
|
|
203
|
-
|
|
243
|
+
margin: 0;
|
|
204
244
|
transition: background-color 0.4s ease-in-out, border-color 0.4s ease-in-out;
|
|
205
245
|
}
|
|
206
246
|
|
|
@@ -215,11 +255,12 @@ pre > code {
|
|
|
215
255
|
position: absolute;
|
|
216
256
|
top: 0;
|
|
217
257
|
right: 0;
|
|
218
|
-
|
|
258
|
+
margin: 1px;
|
|
259
|
+
background: var(--color-bg-alt-solid);
|
|
219
260
|
color: var(--color-hint);
|
|
220
261
|
border: none;
|
|
221
262
|
border-radius: 0.25rem;
|
|
222
|
-
padding: 0
|
|
263
|
+
padding: 0;
|
|
223
264
|
cursor: pointer;
|
|
224
265
|
font-size: 0.75rem;
|
|
225
266
|
z-index: 10;
|
|
@@ -229,7 +270,7 @@ pre > code {
|
|
|
229
270
|
justify-content: center;
|
|
230
271
|
width: 1.5rem;
|
|
231
272
|
height: 1.5rem;
|
|
232
|
-
opacity: 0.
|
|
273
|
+
opacity: 0.9;
|
|
233
274
|
}
|
|
234
275
|
|
|
235
276
|
.code-copy-button:hover {
|
|
@@ -240,7 +281,6 @@ pre > code {
|
|
|
240
281
|
|
|
241
282
|
.code-copy-button.copied {
|
|
242
283
|
color: var(--color-success);
|
|
243
|
-
opacity: 1;
|
|
244
284
|
}
|
|
245
285
|
|
|
246
286
|
.code-copy-button svg {
|
|
@@ -248,6 +288,44 @@ pre > code {
|
|
|
248
288
|
height: 0.875rem;
|
|
249
289
|
}
|
|
250
290
|
|
|
291
|
+
img {
|
|
292
|
+
margin: 1rem 0;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
details {
|
|
296
|
+
font-family: var(--font-sans);
|
|
297
|
+
color: var(--color-text);
|
|
298
|
+
|
|
299
|
+
border: 1px solid var(--color-hint-gentle);
|
|
300
|
+
border-radius: 3px;
|
|
301
|
+
margin: 0.75rem 0;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
summary {
|
|
305
|
+
color: var(--color-secondary);
|
|
306
|
+
padding: .5rem 1rem;
|
|
307
|
+
cursor: pointer;
|
|
308
|
+
user-select: none;
|
|
309
|
+
background: var(--color-bg-alt);
|
|
310
|
+
transition: all 0.15s ease-in-out;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
summary:hover {
|
|
314
|
+
color: var(--color-primary-light);
|
|
315
|
+
{# background: var(--color-hover-bg); #}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/* keep the border on the summary when open so it blends */
|
|
319
|
+
details[open] summary {
|
|
320
|
+
border-bottom: 1px solid var(--color-hint-gentle);
|
|
321
|
+
}
|
|
322
|
+
/* focus ring for a11y */
|
|
323
|
+
summary:focus-visible {
|
|
324
|
+
outline: 3px solid var(--color-primary);
|
|
325
|
+
outline-offset: 2px;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
|
|
251
329
|
hr {
|
|
252
330
|
border: none;
|
|
253
331
|
height: 1.5rem;
|
|
@@ -270,6 +348,7 @@ hr:before {
|
|
|
270
348
|
{% endblock typography %}
|
|
271
349
|
|
|
272
350
|
{% block long_text_styles %}
|
|
351
|
+
|
|
273
352
|
/* Long text stylings, for nicely formatting blog post length or longer texts. */
|
|
274
353
|
|
|
275
354
|
.long-text {
|
|
@@ -289,23 +368,36 @@ hr:before {
|
|
|
289
368
|
|
|
290
369
|
.long-text h3 {
|
|
291
370
|
font-family: var(--font-sans);
|
|
292
|
-
font-weight:
|
|
293
|
-
font-size: 1.05rem;
|
|
371
|
+
font-weight: 565;
|
|
294
372
|
text-transform: uppercase;
|
|
295
373
|
letter-spacing: 0.025em;
|
|
296
374
|
}
|
|
297
375
|
|
|
298
376
|
.long-text h4 {
|
|
377
|
+
font-family: var(--font-sans);
|
|
378
|
+
font-weight: 650;
|
|
379
|
+
letter-spacing: 0.02em;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.long-text h5 {
|
|
299
383
|
font-family: var(--font-serif);
|
|
300
384
|
font-weight: 700;
|
|
301
385
|
}
|
|
302
386
|
|
|
387
|
+
.long-text h6 {
|
|
388
|
+
font-family: var(--font-serif);
|
|
389
|
+
font-weight: 400;
|
|
390
|
+
font-style: italic;
|
|
391
|
+
}
|
|
392
|
+
|
|
303
393
|
.subtitle {
|
|
304
394
|
font-family: var(--font-serif);
|
|
305
395
|
font-style: italic;
|
|
306
396
|
font-size: 1rem;
|
|
307
397
|
}
|
|
308
398
|
|
|
399
|
+
/* Adjustments to long text for pure sans-serif pages. */
|
|
400
|
+
|
|
309
401
|
.long-text .sans-text {
|
|
310
402
|
font-family: var(--font-sans);
|
|
311
403
|
}
|
|
@@ -333,11 +425,11 @@ hr:before {
|
|
|
333
425
|
|
|
334
426
|
.long-text .sans-text h3 {
|
|
335
427
|
font-family: var(--font-sans);
|
|
336
|
-
font-size: 1.
|
|
428
|
+
font-size: 1.1rem;
|
|
337
429
|
font-weight: var(--font-weight-sans-bold);
|
|
338
430
|
text-transform: uppercase;
|
|
339
431
|
letter-spacing: 0.03em;
|
|
340
|
-
margin-top:
|
|
432
|
+
margin-top: 1rem;
|
|
341
433
|
margin-bottom: 0.8rem;
|
|
342
434
|
}
|
|
343
435
|
{% endblock long_text_styles %}
|
|
@@ -356,6 +448,7 @@ table {
|
|
|
356
448
|
}
|
|
357
449
|
|
|
358
450
|
th {
|
|
451
|
+
font-weight: var(--font-weight-sans-bold);
|
|
359
452
|
text-transform: uppercase;
|
|
360
453
|
letter-spacing: 0.03em;
|
|
361
454
|
border-bottom: 1px solid var(--color-border-hint);
|
|
@@ -378,13 +471,24 @@ tbody tr:nth-child(even) {
|
|
|
378
471
|
|
|
379
472
|
/* Container for wide tables to allow tables to break out of parent width. */
|
|
380
473
|
.table-container {
|
|
381
|
-
{# max-width: calc(100vw - 6rem); #}
|
|
382
474
|
position: relative;
|
|
383
|
-
left: 50%;
|
|
384
|
-
transform: translateX(-50%);
|
|
385
475
|
box-sizing: border-box;
|
|
386
476
|
margin: 2rem 0;
|
|
387
477
|
background-color: var(--color-bg-solid);
|
|
478
|
+
/* Default: center tables within their container */
|
|
479
|
+
left: 50%;
|
|
480
|
+
transform: translateX(-50%);
|
|
481
|
+
/* Prevent container from expanding beyond its content area */
|
|
482
|
+
overflow-x: auto;
|
|
483
|
+
overflow-y: visible;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/* When TOC is present, simplify table container positioning */
|
|
487
|
+
.content-with-toc.has-toc .table-container {
|
|
488
|
+
/* Within grid layout, position relative to the grid column */
|
|
489
|
+
left: 50%;
|
|
490
|
+
transform: translateX(-50%);
|
|
491
|
+
/* Let the table width be controlled by the responsive styles */
|
|
388
492
|
}
|
|
389
493
|
{% endblock table_styles %}
|
|
390
494
|
|
|
@@ -434,20 +538,89 @@ sup {
|
|
|
434
538
|
}
|
|
435
539
|
.table-container {
|
|
436
540
|
width: calc(100vw - 6rem);
|
|
541
|
+
/* Ensure container doesn't expand beyond its width */
|
|
542
|
+
max-width: calc(100vw - 6rem);
|
|
543
|
+
contain: layout inline-size;
|
|
437
544
|
}
|
|
438
545
|
|
|
439
546
|
/* Apply shadow to long-text containers on larger screens */
|
|
440
547
|
.long-text {
|
|
548
|
+
border: 1px solid var(--color-hint-gentle);
|
|
441
549
|
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 -2px 6px -1px rgba(0, 0, 0, 0.07);
|
|
442
550
|
}
|
|
443
551
|
/* But remove shadow when wrapped in no-shadow class */
|
|
444
552
|
.no-shadow .long-text {
|
|
445
|
-
box-shadow: none
|
|
553
|
+
box-shadow: none;
|
|
554
|
+
border: none;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/* Handle TOC layouts specially - tables should bleed within their grid column */
|
|
559
|
+
@media (min-width: 1200px) {
|
|
560
|
+
.content-with-toc.has-toc {
|
|
561
|
+
/* Define reusable values for clarity */
|
|
562
|
+
--content-width: 48rem;
|
|
563
|
+
--content-min-gap: 2rem;
|
|
564
|
+
--table-right-margin: 2rem;
|
|
565
|
+
--long-text-padding: 4rem; /* md:px-16 = 4rem */
|
|
566
|
+
|
|
567
|
+
/* Where content would be if centered in viewport */
|
|
568
|
+
--content-centered-left: calc((100vw - var(--content-width)) / 2);
|
|
569
|
+
|
|
570
|
+
/* Content's left margin within its grid column */
|
|
571
|
+
--content-margin-left: max(var(--content-min-gap), calc(var(--content-centered-left) - var(--toc-width)));
|
|
572
|
+
|
|
573
|
+
/* Content text's actual position from viewport left edge (excluding padding) */
|
|
574
|
+
--content-text-viewport-left: calc(var(--toc-width) + var(--content-margin-left));
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/* When TOC is present, tables should align with main content and bleed right */
|
|
578
|
+
.content-with-toc.has-toc .table-container {
|
|
579
|
+
/* Remove default positioning */
|
|
580
|
+
left: 0;
|
|
581
|
+
transform: none;
|
|
582
|
+
|
|
583
|
+
/* Pull table left to align with content's text position */
|
|
584
|
+
/* Need to compensate for both content margin AND long-text padding */
|
|
585
|
+
margin-left: calc(-1 * (var(--content-margin-left) + var(--long-text-padding)));
|
|
586
|
+
|
|
587
|
+
/* Table bleeds wide as can fit */
|
|
588
|
+
width: calc(100vw - var(--content-text-viewport-left) - var(--table-right-margin));
|
|
589
|
+
max-width: calc(100vw - var(--content-text-viewport-left) - var(--table-right-margin));
|
|
590
|
+
|
|
591
|
+
/* Ensure horizontal scroll works properly without expanding container */
|
|
592
|
+
overflow-x: auto;
|
|
593
|
+
overflow-y: visible;
|
|
594
|
+
contain: layout inline-size;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.content-with-toc.has-toc table {
|
|
598
|
+
/* Let table fill its container */
|
|
599
|
+
width: 100%;
|
|
600
|
+
max-width: none;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/* But ensure tables don't exceed their grid column space */
|
|
604
|
+
.content-with-toc.has-toc .long-text {
|
|
605
|
+
/* The content area needs to allow tables to bleed beyond the text width */
|
|
606
|
+
overflow: visible;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/* Medium screens (768px - TOC breakpoint) - no TOC, tables should bleed but not as wide */
|
|
611
|
+
@media (min-width: 768px) and (max-width: 1199px) {
|
|
612
|
+
table {
|
|
613
|
+
width: calc(100vw - 6rem);
|
|
614
|
+
max-width: calc(100vw - 6rem);
|
|
615
|
+
}
|
|
616
|
+
.table-container {
|
|
617
|
+
width: calc(100vw - 6rem);
|
|
618
|
+
max-width: calc(100vw - 6rem);
|
|
446
619
|
}
|
|
447
620
|
}
|
|
448
621
|
|
|
449
622
|
/* Make narrower screens more usable for lists and tables. */
|
|
450
|
-
@media (max-width:
|
|
623
|
+
@media (max-width: 767px) {
|
|
451
624
|
/* Prevent horizontal scrolling on the body */
|
|
452
625
|
body {
|
|
453
626
|
overflow-x: hidden;
|
|
@@ -461,20 +634,26 @@ sup {
|
|
|
461
634
|
|
|
462
635
|
/* Make table containers scrollable without affecting page layout */
|
|
463
636
|
.table-container {
|
|
464
|
-
max-width
|
|
637
|
+
width: calc(100vw - 3rem); /* Fixed width instead of max-width */
|
|
638
|
+
max-width: calc(100vw - 3rem);
|
|
465
639
|
overflow-x: auto;
|
|
640
|
+
overflow-y: visible; /* Ensure vertical overflow is not hidden */
|
|
466
641
|
transform: none;
|
|
467
642
|
left: 0;
|
|
468
643
|
position: relative;
|
|
469
644
|
margin-left: auto;
|
|
470
645
|
margin-right: auto;
|
|
646
|
+
/* Prevent container from expanding beyond its width */
|
|
647
|
+
box-sizing: border-box;
|
|
648
|
+
contain: layout inline-size; /* CSS containment to prevent width expansion */
|
|
471
649
|
}
|
|
472
650
|
|
|
473
651
|
table {
|
|
474
652
|
font-size: var(--font-size-smaller);
|
|
475
|
-
/* Tables can be wider than container */
|
|
653
|
+
/* Tables can be wider than container on mobile */
|
|
476
654
|
width: auto;
|
|
477
655
|
min-width: 100%;
|
|
656
|
+
max-width: none;
|
|
478
657
|
}
|
|
479
658
|
|
|
480
659
|
ul, ol {
|
|
@@ -50,57 +50,68 @@
|
|
|
50
50
|
<link rel="preload" as="font" type="font/woff2" crossorigin
|
|
51
51
|
href="https://cdn.jsdelivr.net/fontsource/fonts/source-sans-3:vf@latest/latin-wght-italic.woff2" />
|
|
52
52
|
|
|
53
|
-
<
|
|
53
|
+
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
|
54
54
|
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js" defer></script>
|
|
55
55
|
{% endblock head_basic %}
|
|
56
56
|
|
|
57
57
|
{% block head_extra %}{% endblock head_extra %}
|
|
58
58
|
|
|
59
59
|
<style>
|
|
60
|
-
|
|
61
60
|
body {
|
|
62
61
|
background: var(--color-bg);
|
|
63
62
|
color: var(--color-text);
|
|
64
63
|
transition: background 0.4s ease-in-out, color 0.4s ease-in-out;
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
right: 1rem;
|
|
71
|
-
background: transparent;
|
|
72
|
-
color: var(--color-hint);
|
|
66
|
+
.button {
|
|
67
|
+
color: var(--color-hint-strong);
|
|
68
|
+
background: var(--color-bg);
|
|
73
69
|
border: none;
|
|
74
70
|
padding: 0;
|
|
75
71
|
border-radius: 0.3rem;
|
|
76
72
|
cursor: pointer;
|
|
77
73
|
font-size: 1rem;
|
|
78
|
-
z-index: 100;
|
|
79
|
-
transition: all 0.2s ease-in-out;
|
|
80
74
|
display: flex;
|
|
81
75
|
align-items: center;
|
|
82
76
|
justify-content: center;
|
|
83
|
-
width: 2.
|
|
84
|
-
height: 2.
|
|
77
|
+
width: 2.2rem;
|
|
78
|
+
height: 2.2rem;
|
|
79
|
+
|
|
80
|
+
/* Separate transitions for theme vs interaction */
|
|
81
|
+
transition: background-color 0.4s ease-in-out,
|
|
82
|
+
color 0.4s ease-in-out,
|
|
83
|
+
transform 0.2s ease-in-out,
|
|
84
|
+
box-shadow 0.2s ease-in-out;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
.
|
|
87
|
+
.button:hover {
|
|
88
88
|
background: var(--color-hover-bg);
|
|
89
89
|
color: var(--color-primary);
|
|
90
|
+
transition: background-color 0.4s ease-in-out, color 0.4s ease-in-out;
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
.button svg {
|
|
94
|
+
width: 1.2rem;
|
|
95
|
+
height: 1.2rem;
|
|
96
|
+
transition: background-color 0.4s ease-in-out, color 0.4s ease-in-out;
|
|
94
97
|
}
|
|
95
98
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
|
|
100
|
+
/* Positioning class for fixed buttons */
|
|
101
|
+
.fixed-button {
|
|
102
|
+
position: fixed;
|
|
103
|
+
top: 1rem;
|
|
99
104
|
}
|
|
100
105
|
|
|
101
|
-
.
|
|
102
|
-
|
|
103
|
-
|
|
106
|
+
.floating-button {
|
|
107
|
+
border: 1px solid var(--color-hint-gentle);
|
|
108
|
+
background: var(--color-bg-alt);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* Specific positioning and z-index for theme toggle */
|
|
112
|
+
.theme-toggle {
|
|
113
|
+
right: 1rem;
|
|
114
|
+
z-index: 100;
|
|
104
115
|
}
|
|
105
116
|
|
|
106
117
|
{% block font_faces %}
|
|
@@ -178,7 +189,7 @@
|
|
|
178
189
|
<body>
|
|
179
190
|
{% block theme_toggle %}
|
|
180
191
|
{% if show_theme_toggle %}
|
|
181
|
-
<button class="theme-toggle" aria-label="toggle dark mode">
|
|
192
|
+
<button class="button fixed-button theme-toggle" aria-label="toggle dark mode">
|
|
182
193
|
<i data-feather="moon"></i>
|
|
183
194
|
</button>
|
|
184
195
|
{% endif %}
|
|
@@ -197,11 +208,20 @@
|
|
|
197
208
|
document.addEventListener('DOMContentLoaded', () => {
|
|
198
209
|
// Add copy buttons to code blocks
|
|
199
210
|
document.querySelectorAll('pre').forEach(pre => {
|
|
200
|
-
// Skip if already has a copy button
|
|
201
|
-
if (pre.
|
|
211
|
+
// Skip if already has a copy button (check parent for wrapper)
|
|
212
|
+
if (pre.parentElement.classList.contains('code-block-wrapper')) {
|
|
202
213
|
return;
|
|
203
214
|
}
|
|
204
215
|
|
|
216
|
+
// Create wrapper div
|
|
217
|
+
const wrapper = document.createElement('div');
|
|
218
|
+
wrapper.className = 'code-block-wrapper';
|
|
219
|
+
|
|
220
|
+
// Insert wrapper before pre and move pre inside it
|
|
221
|
+
pre.parentNode.insertBefore(wrapper, pre);
|
|
222
|
+
wrapper.appendChild(pre);
|
|
223
|
+
|
|
224
|
+
// Create copy button
|
|
205
225
|
const copyButton = document.createElement('button');
|
|
206
226
|
copyButton.className = 'code-copy-button';
|
|
207
227
|
copyButton.setAttribute('aria-label', 'Copy code');
|
|
@@ -229,7 +249,8 @@
|
|
|
229
249
|
});
|
|
230
250
|
});
|
|
231
251
|
|
|
232
|
-
pre
|
|
252
|
+
// Add button to wrapper, not to pre
|
|
253
|
+
wrapper.appendChild(copyButton);
|
|
233
254
|
});
|
|
234
255
|
|
|
235
256
|
// Theme toggle (if present on page)
|
|
@@ -307,8 +328,9 @@
|
|
|
307
328
|
}
|
|
308
329
|
});
|
|
309
330
|
|
|
310
|
-
|
|
331
|
+
|
|
311
332
|
</script>
|
|
333
|
+
{% block scripts_extra %}{% endblock scripts_extra %}
|
|
312
334
|
{% endblock scripts %}
|
|
313
335
|
|
|
314
336
|
{% block analytics %}{% endblock analytics %}
|