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
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
/* -----------------------------------------------------------------------------
|
|
2
|
+
Tooltip CSS Variables
|
|
3
|
+
----------------------------------------------------------------------------- */
|
|
4
|
+
|
|
5
|
+
:root {
|
|
6
|
+
/* Tooltip spacing */
|
|
7
|
+
--tooltip-viewport-margin: 10px;
|
|
8
|
+
--tooltip-gap: 10px;
|
|
9
|
+
--tooltip-mobile-top-margin: 20px;
|
|
10
|
+
--tooltip-arrow-size: 5px;
|
|
11
|
+
|
|
12
|
+
/* Tooltip sizing */
|
|
13
|
+
--tooltip-max-width: 20rem;
|
|
14
|
+
--tooltip-min-width: 8rem;
|
|
15
|
+
--tooltip-padding: 0.5rem 0.75rem;
|
|
16
|
+
|
|
17
|
+
/* Footnote tooltip sizing */
|
|
18
|
+
--footnote-tooltip-max-width: 25rem;
|
|
19
|
+
--footnote-tooltip-min-width: 12rem;
|
|
20
|
+
|
|
21
|
+
/* Wide screen tooltip sizing */
|
|
22
|
+
--tooltip-wide-max-width: 22rem;
|
|
23
|
+
--tooltip-wide-min-width: 16rem;
|
|
24
|
+
--footnote-wide-max-width: 24rem;
|
|
25
|
+
--footnote-wide-min-width: 18rem;
|
|
26
|
+
|
|
27
|
+
/* Extra wide screen sizing */
|
|
28
|
+
--tooltip-extra-wide-max-width: 28rem;
|
|
29
|
+
--tooltip-extra-wide-min-width: 20rem;
|
|
30
|
+
--footnote-extra-wide-max-width: 30rem;
|
|
31
|
+
--footnote-extra-wide-min-width: 22rem;
|
|
32
|
+
|
|
33
|
+
/* Mobile specific */
|
|
34
|
+
--tooltip-mobile-padding: 0.75rem 1rem;
|
|
35
|
+
--tooltip-mobile-max-width: 48rem; /* Maximum width for mobile tooltips */
|
|
36
|
+
|
|
37
|
+
/* Transitions */
|
|
38
|
+
--tooltip-transition-duration: 0.6s;
|
|
39
|
+
--tooltip-transition-timing: ease-in-out;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* -----------------------------------------------------------------------------
|
|
43
|
+
Real DOM Element Tooltip Foundation
|
|
44
|
+
----------------------------------------------------------------------------- */
|
|
45
|
+
|
|
46
|
+
/* Tooltip container */
|
|
47
|
+
[data-tooltip-trigger] {
|
|
48
|
+
position: relative;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Base tooltip element - ALL tooltips inherit these styles */
|
|
52
|
+
.tooltip-element {
|
|
53
|
+
position: absolute;
|
|
54
|
+
visibility: hidden;
|
|
55
|
+
opacity: 0;
|
|
56
|
+
pointer-events: none;
|
|
57
|
+
/* Only transition opacity and visibility, not transform to avoid movement */
|
|
58
|
+
transition: opacity var(--tooltip-transition-duration) var(--tooltip-transition-timing),
|
|
59
|
+
visibility var(--tooltip-transition-duration) var(--tooltip-transition-timing);
|
|
60
|
+
/* Ensure no transition on positioning properties */
|
|
61
|
+
transition-property: opacity, visibility;
|
|
62
|
+
z-index: 1000;
|
|
63
|
+
|
|
64
|
+
/* Tooltip styling - matching TOC active item */
|
|
65
|
+
background: var(--color-bg-selected);
|
|
66
|
+
border: 1px solid var(--color-border-hint);
|
|
67
|
+
border-left: 2px solid var(--color-primary);
|
|
68
|
+
color: var(--color-secondary);
|
|
69
|
+
font-family: var(--font-sans);
|
|
70
|
+
font-size: var(--font-size-small);
|
|
71
|
+
line-height: 1.4;
|
|
72
|
+
padding: var(--tooltip-padding);
|
|
73
|
+
border-radius: 0; /* Square corners for all tooltips */
|
|
74
|
+
|
|
75
|
+
/* Sizing and text handling */
|
|
76
|
+
width: max-content;
|
|
77
|
+
max-width: var(--tooltip-max-width);
|
|
78
|
+
min-width: var(--tooltip-min-width);
|
|
79
|
+
white-space: normal;
|
|
80
|
+
word-break: normal;
|
|
81
|
+
overflow-wrap: break-word;
|
|
82
|
+
hyphens: auto;
|
|
83
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Tooltip arrow - base styles */
|
|
87
|
+
.tooltip-element::after {
|
|
88
|
+
content: '';
|
|
89
|
+
position: absolute;
|
|
90
|
+
border: var(--tooltip-arrow-size) solid transparent;
|
|
91
|
+
z-index: 1001;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* Show tooltip when visible */
|
|
95
|
+
.tooltip-element.tooltip-visible {
|
|
96
|
+
visibility: visible;
|
|
97
|
+
opacity: 1;
|
|
98
|
+
transform: translateY(0);
|
|
99
|
+
pointer-events: auto;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* Ensure tooltip content is interactive when visible */
|
|
103
|
+
.tooltip-element.tooltip-visible * {
|
|
104
|
+
pointer-events: auto;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Tooltip hover state */
|
|
108
|
+
.tooltip-element:hover {
|
|
109
|
+
background: var(--color-hover-bg);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* -----------------------------------------------------------------------------
|
|
113
|
+
General Tooltip Positioning - Using margin variables
|
|
114
|
+
----------------------------------------------------------------------------- */
|
|
115
|
+
|
|
116
|
+
/* Default: Top positioning */
|
|
117
|
+
.tooltip-element.tooltip-top {
|
|
118
|
+
bottom: 100%;
|
|
119
|
+
left: 50%;
|
|
120
|
+
transform: translateX(-50%) translateY(0.125rem);
|
|
121
|
+
margin-bottom: var(--tooltip-gap);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.tooltip-element.tooltip-top::after {
|
|
125
|
+
top: 100%;
|
|
126
|
+
left: 50%;
|
|
127
|
+
transform: translateX(-50%);
|
|
128
|
+
border-top-color: var(--color-border-hint);
|
|
129
|
+
margin-top: calc(-1 * var(--tooltip-arrow-size));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Active state overrides for top positioning */
|
|
133
|
+
.tooltip-element.tooltip-top.tooltip-visible {
|
|
134
|
+
transform: translateX(-50%) translateY(0);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Bottom positioning */
|
|
138
|
+
.tooltip-element.tooltip-bottom {
|
|
139
|
+
top: 100%;
|
|
140
|
+
left: 50%;
|
|
141
|
+
transform: translateX(-50%) translateY(-0.125rem);
|
|
142
|
+
margin-top: var(--tooltip-gap);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.tooltip-element.tooltip-bottom::after {
|
|
146
|
+
bottom: 100%;
|
|
147
|
+
left: 50%;
|
|
148
|
+
transform: translateX(-50%);
|
|
149
|
+
border-bottom-color: var(--color-border-hint);
|
|
150
|
+
margin-bottom: calc(-1 * var(--tooltip-arrow-size));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.tooltip-element.tooltip-bottom.tooltip-visible {
|
|
154
|
+
transform: translateX(-50%) translateY(0);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* Left positioning */
|
|
158
|
+
.tooltip-element.tooltip-left {
|
|
159
|
+
right: 100%;
|
|
160
|
+
top: 50%;
|
|
161
|
+
transform: translateX(0.125rem) translateY(-50%);
|
|
162
|
+
margin-right: var(--tooltip-gap);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.tooltip-element.tooltip-left::after {
|
|
166
|
+
left: 100%;
|
|
167
|
+
top: 50%;
|
|
168
|
+
transform: translateY(-50%);
|
|
169
|
+
border-left-color: var(--color-border-hint);
|
|
170
|
+
margin-left: calc(-1 * var(--tooltip-arrow-size));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.tooltip-element.tooltip-left.tooltip-visible {
|
|
174
|
+
transform: translateX(0) translateY(-50%);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/* Right positioning */
|
|
178
|
+
.tooltip-element.tooltip-right {
|
|
179
|
+
left: 100%;
|
|
180
|
+
top: 50%;
|
|
181
|
+
transform: translateX(-0.125rem) translateY(-50%);
|
|
182
|
+
margin-left: var(--tooltip-gap);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.tooltip-element.tooltip-right::after {
|
|
186
|
+
right: 100%;
|
|
187
|
+
top: 50%;
|
|
188
|
+
transform: translateY(-50%);
|
|
189
|
+
border-right-color: var(--color-border-hint);
|
|
190
|
+
margin-right: calc(-1 * var(--tooltip-arrow-size));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.tooltip-element.tooltip-right.tooltip-visible {
|
|
194
|
+
transform: translateX(0) translateY(-50%);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/* -----------------------------------------------------------------------------
|
|
198
|
+
Diagonal Tooltip Positioning
|
|
199
|
+
----------------------------------------------------------------------------- */
|
|
200
|
+
|
|
201
|
+
/* Bottom-right positioning (default preference) */
|
|
202
|
+
.tooltip-element.tooltip-bottom-right {
|
|
203
|
+
top: 100%;
|
|
204
|
+
left: 0;
|
|
205
|
+
transform: translateY(-0.125rem);
|
|
206
|
+
margin-top: var(--tooltip-gap);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.tooltip-element.tooltip-bottom-right::after {
|
|
210
|
+
bottom: 100%;
|
|
211
|
+
left: 1rem;
|
|
212
|
+
transform: translateX(-50%);
|
|
213
|
+
border-bottom-color: var(--color-border-hint);
|
|
214
|
+
margin-bottom: calc(-1 * var(--tooltip-arrow-size));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.tooltip-element.tooltip-bottom-right.tooltip-visible {
|
|
218
|
+
transform: translateY(0);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/* Bottom-left positioning */
|
|
222
|
+
.tooltip-element.tooltip-bottom-left {
|
|
223
|
+
top: 100%;
|
|
224
|
+
right: 0;
|
|
225
|
+
transform: translateY(-0.125rem);
|
|
226
|
+
margin-top: var(--tooltip-gap);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.tooltip-element.tooltip-bottom-left::after {
|
|
230
|
+
bottom: 100%;
|
|
231
|
+
right: 1rem;
|
|
232
|
+
transform: translateX(50%);
|
|
233
|
+
border-bottom-color: var(--color-border-hint);
|
|
234
|
+
margin-bottom: calc(-1 * var(--tooltip-arrow-size));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.tooltip-element.tooltip-bottom-left.tooltip-visible {
|
|
238
|
+
transform: translateY(0);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/* Top-right positioning */
|
|
242
|
+
.tooltip-element.tooltip-top-right {
|
|
243
|
+
bottom: 100%;
|
|
244
|
+
left: 0;
|
|
245
|
+
transform: translateY(0.125rem);
|
|
246
|
+
margin-bottom: var(--tooltip-gap);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.tooltip-element.tooltip-top-right::after {
|
|
250
|
+
top: 100%;
|
|
251
|
+
left: 1rem;
|
|
252
|
+
transform: translateX(-50%);
|
|
253
|
+
border-top-color: var(--color-border-hint);
|
|
254
|
+
margin-top: calc(-1 * var(--tooltip-arrow-size));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.tooltip-element.tooltip-top-right.tooltip-visible {
|
|
258
|
+
transform: translateY(0);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/* Top-left positioning */
|
|
262
|
+
.tooltip-element.tooltip-top-left {
|
|
263
|
+
bottom: 100%;
|
|
264
|
+
right: 0;
|
|
265
|
+
transform: translateY(0.125rem);
|
|
266
|
+
margin-bottom: var(--tooltip-gap);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.tooltip-element.tooltip-top-left::after {
|
|
270
|
+
top: 100%;
|
|
271
|
+
right: 1rem;
|
|
272
|
+
transform: translateX(50%);
|
|
273
|
+
border-top-color: var(--color-border-hint);
|
|
274
|
+
margin-top: calc(-1 * var(--tooltip-arrow-size));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.tooltip-element.tooltip-top-left.tooltip-visible {
|
|
278
|
+
transform: translateY(0);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* -----------------------------------------------------------------------------
|
|
282
|
+
Mobile Bottom Positioning
|
|
283
|
+
----------------------------------------------------------------------------- */
|
|
284
|
+
|
|
285
|
+
/* Mobile-specific bottom positioning */
|
|
286
|
+
.tooltip-element.tooltip-mobile-bottom {
|
|
287
|
+
/* Position handled by JS, but ensure fixed positioning */
|
|
288
|
+
position: fixed !important;
|
|
289
|
+
/* No transform needed */
|
|
290
|
+
transform: none !important;
|
|
291
|
+
margin: 0;
|
|
292
|
+
|
|
293
|
+
/* Width handled by JS (calc(100vw - 2rem)) */
|
|
294
|
+
box-sizing: border-box;
|
|
295
|
+
width: calc(100vw - 2rem) !important;
|
|
296
|
+
|
|
297
|
+
/* Content constraints */
|
|
298
|
+
max-width: none !important;
|
|
299
|
+
/* Dynamic padding: at least 1rem, but increases to center content within 40rem max */
|
|
300
|
+
padding-left: max(1rem, calc((100% - 40rem) / 2)) !important;
|
|
301
|
+
padding-right: max(1rem, calc((100% - 40rem) / 2)) !important;
|
|
302
|
+
|
|
303
|
+
/* Left align text for readability */
|
|
304
|
+
text-align: left;
|
|
305
|
+
|
|
306
|
+
/* Use same shadow as wide-right for consistency */
|
|
307
|
+
box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.15);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/* Remove arrow for mobile bottom tooltips */
|
|
311
|
+
.tooltip-element.tooltip-mobile-bottom::after {
|
|
312
|
+
display: none;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/* Ensure mobile tooltips are visible when active */
|
|
316
|
+
.tooltip-element.tooltip-mobile-bottom.tooltip-visible {
|
|
317
|
+
transform: none !important;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/* -----------------------------------------------------------------------------
|
|
321
|
+
Footnote-Specific Tooltips (extends base tooltip styling)
|
|
322
|
+
----------------------------------------------------------------------------- */
|
|
323
|
+
|
|
324
|
+
/* Footnote reference styling */
|
|
325
|
+
.footnote-ref a[data-tooltip-trigger] {
|
|
326
|
+
transition: color 0.4s ease-in-out;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.footnote-ref a[data-tooltip-trigger]:hover {
|
|
330
|
+
color: var(--color-primary-light);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/* Enhanced footnote tooltip styling - only overrides what's different */
|
|
334
|
+
.footnote-element {
|
|
335
|
+
/* Larger max-width for footnote content */
|
|
336
|
+
max-width: var(--footnote-tooltip-max-width);
|
|
337
|
+
min-width: var(--footnote-tooltip-min-width);
|
|
338
|
+
/* Better typography for longer footnote text */
|
|
339
|
+
line-height: 1.5;
|
|
340
|
+
text-align: left;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/* Footnote tooltip positioning adjustments */
|
|
344
|
+
.footnote-element.tooltip-top {
|
|
345
|
+
/* Position slightly higher to avoid covering the link */
|
|
346
|
+
margin-bottom: calc(var(--tooltip-gap) + 5px);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/* Links within tooltips - applies to ALL tooltips */
|
|
350
|
+
.tooltip-element a {
|
|
351
|
+
color: var(--color-primary);
|
|
352
|
+
text-decoration: underline;
|
|
353
|
+
cursor: pointer;
|
|
354
|
+
pointer-events: auto;
|
|
355
|
+
overflow-wrap: break-word;
|
|
356
|
+
word-break: normal;
|
|
357
|
+
transition: color 0.2s ease-in-out;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.tooltip-element a:hover {
|
|
361
|
+
color: var(--color-primary-light);
|
|
362
|
+
text-decoration: underline;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/* Hide the footnote back-link in tooltips */
|
|
366
|
+
.footnote-element .footnote {
|
|
367
|
+
display: none;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/* Text breaking rules for all tooltips */
|
|
371
|
+
.tooltip-element .force-break,
|
|
372
|
+
.tooltip-element code,
|
|
373
|
+
.tooltip-element pre {
|
|
374
|
+
word-break: break-all;
|
|
375
|
+
overflow-wrap: break-word;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
.tooltip-element p,
|
|
379
|
+
.tooltip-element span,
|
|
380
|
+
.tooltip-element div {
|
|
381
|
+
word-break: normal;
|
|
382
|
+
overflow-wrap: break-word;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/* -----------------------------------------------------------------------------
|
|
386
|
+
Wide Screen Tooltip Positioning (Right of Main Content)
|
|
387
|
+
----------------------------------------------------------------------------- */
|
|
388
|
+
|
|
389
|
+
/* Position tooltips to the right of main content on wide screens */
|
|
390
|
+
@media (min-width: 1200px) {
|
|
391
|
+
.tooltip-element.tooltip-wide-right {
|
|
392
|
+
/* Position absolutely to viewport for placement to right of main content */
|
|
393
|
+
position: fixed;
|
|
394
|
+
/* Positioning handled by JS */
|
|
395
|
+
left: auto;
|
|
396
|
+
right: auto;
|
|
397
|
+
top: auto;
|
|
398
|
+
bottom: auto;
|
|
399
|
+
transform: translateX(0.125rem) translateY(-50%);
|
|
400
|
+
margin: 0;
|
|
401
|
+
|
|
402
|
+
/* Larger size for side placement */
|
|
403
|
+
max-width: var(--tooltip-wide-max-width);
|
|
404
|
+
min-width: var(--tooltip-wide-min-width);
|
|
405
|
+
/* Ensure text wraps properly when constrained */
|
|
406
|
+
word-wrap: break-word;
|
|
407
|
+
overflow-wrap: break-word;
|
|
408
|
+
|
|
409
|
+
/* Enhanced shadow for sidebar placement */
|
|
410
|
+
box-shadow: 0 8px 25px -3px rgba(0, 0, 0, 0.15), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.tooltip-element.tooltip-wide-right::after {
|
|
414
|
+
/* Arrow pointing left towards the content */
|
|
415
|
+
right: 100%;
|
|
416
|
+
top: 50%;
|
|
417
|
+
left: auto;
|
|
418
|
+
bottom: auto;
|
|
419
|
+
transform: translateY(-50%);
|
|
420
|
+
border-right-color: var(--color-border-hint);
|
|
421
|
+
border-top-color: transparent;
|
|
422
|
+
border-bottom-color: transparent;
|
|
423
|
+
border-left-color: transparent;
|
|
424
|
+
margin: 0;
|
|
425
|
+
margin-right: calc(-1 * var(--tooltip-arrow-size));
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.tooltip-element.tooltip-wide-right.tooltip-visible {
|
|
429
|
+
transform: translateX(0) translateY(-50%);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/* Ensure footnote tooltips use appropriate sizing on wide screens */
|
|
433
|
+
.footnote-element.tooltip-wide-right {
|
|
434
|
+
max-width: var(--footnote-wide-max-width);
|
|
435
|
+
min-width: var(--footnote-wide-min-width);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/* Extra wide screens - make tooltips even wider */
|
|
440
|
+
@media (min-width: 1600px) {
|
|
441
|
+
.tooltip-element.tooltip-wide-right {
|
|
442
|
+
max-width: var(--tooltip-extra-wide-max-width);
|
|
443
|
+
min-width: var(--tooltip-extra-wide-min-width);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.footnote-element.tooltip-wide-right {
|
|
447
|
+
max-width: var(--footnote-extra-wide-max-width);
|
|
448
|
+
min-width: var(--footnote-extra-wide-min-width);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/* Medium screens - use standard positioning with constrained width */
|
|
453
|
+
@media (min-width: 641px) and (max-width: 1199px) {
|
|
454
|
+
.tooltip-element {
|
|
455
|
+
/* Constrain width to fit within content area */
|
|
456
|
+
max-width: min(var(--tooltip-max-width), calc(100vw - 4rem));
|
|
457
|
+
box-sizing: border-box;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
.footnote-element {
|
|
461
|
+
max-width: min(var(--footnote-tooltip-max-width), calc(100vw - 4rem));
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/* Narrow screens - bottom-centered tooltips (640px and below) */
|
|
466
|
+
@media (max-width: 640px) {
|
|
467
|
+
.tooltip-element {
|
|
468
|
+
/* Ensure readable font size on mobile */
|
|
469
|
+
font-size: var(--font-size-small);
|
|
470
|
+
|
|
471
|
+
/* Better touch-friendly padding */
|
|
472
|
+
padding: var(--tooltip-mobile-padding);
|
|
473
|
+
|
|
474
|
+
/* Let JS handle all positioning */
|
|
475
|
+
box-sizing: border-box;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/* Non-mobile-bottom tooltips should still be constrained on narrow screens */
|
|
479
|
+
.tooltip-element:not(.tooltip-mobile-bottom) {
|
|
480
|
+
max-width: min(var(--tooltip-max-width), calc(100vw - 2rem)) !important;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
.summary {
|
|
46
46
|
font-family: var(--font-sans);
|
|
47
47
|
font-size: var(--font-size-small);
|
|
48
|
-
margin:
|
|
48
|
+
margin: 1rem 0;
|
|
49
49
|
padding: 1rem;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -166,19 +166,24 @@
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
.annotated-para .para-caption {
|
|
169
|
-
width:
|
|
169
|
+
width: 20%;
|
|
170
170
|
font-size: var(--font-size-smaller);
|
|
171
|
-
order:
|
|
172
|
-
|
|
173
|
-
margin-left: 1.5rem;
|
|
171
|
+
order: 0;
|
|
172
|
+
margin: 0.5rem 1rem 0.5rem 0;
|
|
174
173
|
font-family: var(--font-sans);
|
|
175
174
|
color: var(--color-secondary);
|
|
176
|
-
border-
|
|
177
|
-
padding-
|
|
175
|
+
border-right: 2px solid var(--color-hint);
|
|
176
|
+
padding-right: 0.5rem;
|
|
177
|
+
align-self: center;
|
|
178
|
+
max-height: 15rem;
|
|
179
|
+
overflow-y: auto;
|
|
180
|
+
|
|
181
|
+
scrollbar-width: thin;
|
|
182
|
+
scrollbar-color: var(--color-hint-gentle) transparent;
|
|
178
183
|
}
|
|
179
184
|
|
|
180
185
|
.annotated-para .para {
|
|
181
|
-
width:
|
|
186
|
+
width: 80%;
|
|
182
187
|
order: 1;
|
|
183
188
|
}
|
|
184
189
|
|
|
@@ -5,7 +5,15 @@
|
|
|
5
5
|
<style>
|
|
6
6
|
/* Override Tailwind's bg-white in dark mode */
|
|
7
7
|
[data-theme="dark"] .bg-white {
|
|
8
|
-
background-color: var(--color-bg-alt-solid)
|
|
8
|
+
background-color: var(--color-bg-alt-solid);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* Fallback responsive padding for compatibility */
|
|
12
|
+
@media (min-width: 768px) {
|
|
13
|
+
.content-with-toc .long-text {
|
|
14
|
+
padding-left: 4rem;
|
|
15
|
+
padding-right: 4rem;
|
|
16
|
+
}
|
|
9
17
|
}
|
|
10
18
|
.long-text {
|
|
11
19
|
transition: background 0.4s ease-in-out, color 0.4s ease-in-out;
|
|
@@ -15,34 +23,64 @@
|
|
|
15
23
|
[data-theme="dark"] .long-text {
|
|
16
24
|
background-color: var(--color-bg-alt-solid);
|
|
17
25
|
color: var(--color-text);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/* Adjust shadow for dark mode */
|
|
21
|
-
[data-theme="dark"] .long-text {
|
|
22
26
|
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 -2px 6px -1px rgba(0, 0, 0, 0.2);
|
|
23
27
|
}
|
|
28
|
+
|
|
29
|
+
{% include "components/toc_styles.css.jinja" %}
|
|
30
|
+
{% include "components/tooltip_styles.css.jinja" %}
|
|
24
31
|
</style>
|
|
25
32
|
{% endblock custom_styles %}
|
|
26
33
|
|
|
27
|
-
<!-- simple_webpage begin main_content block -->
|
|
28
34
|
{% block main_content %}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
<div>
|
|
37
|
-
{% block page_content %}
|
|
38
|
-
{% if thumbnail_url %}
|
|
39
|
-
<img class="thumbnail" src="{{ thumbnail_url }}" alt="{{ title }}" />
|
|
35
|
+
<!-- simple_webpage begin main_content block -->
|
|
36
|
+
<div class="content-with-toc" id="content-container">
|
|
37
|
+
<div class="long-text container max-w-3xl mx-auto bg-white py-4 px-6 md:px-16" id="main-content">
|
|
38
|
+
{% block page_title %}
|
|
39
|
+
{% if title and add_title_h1 %}
|
|
40
|
+
<h1 class="text-center text-4xl mt-6 mb-6">{{ title }}</h1>
|
|
40
41
|
{% endif %}
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
{% endblock page_title %}
|
|
43
|
+
|
|
44
|
+
<div>
|
|
45
|
+
{% block page_content %}
|
|
46
|
+
{% if thumbnail_url %}
|
|
47
|
+
<img class="thumbnail" src="{{ thumbnail_url }}" alt="{{ title }}" />
|
|
48
|
+
{% endif %}
|
|
49
|
+
<div class="content">
|
|
50
|
+
{{ content_html | safe }}
|
|
51
|
+
</div>
|
|
52
|
+
{% endblock page_content %}
|
|
43
53
|
</div>
|
|
44
|
-
{% endblock page_content %}
|
|
45
54
|
</div>
|
|
55
|
+
|
|
56
|
+
<!-- Mobile TOC toggle -->
|
|
57
|
+
<button class="button fixed-button floating-button toc-toggle" id="toc-toggle" aria-label="Toggle table of contents" style="display: none;">
|
|
58
|
+
<i data-feather="list"></i>
|
|
59
|
+
</button>
|
|
60
|
+
|
|
61
|
+
<!-- Mobile TOC Backdrop -->
|
|
62
|
+
<div class="toc-backdrop" id="toc-backdrop"></div>
|
|
63
|
+
|
|
64
|
+
<!-- TOC Container -->
|
|
65
|
+
<aside class="toc-container" id="toc-container" aria-label="Table of contents">
|
|
66
|
+
<div class="toc">
|
|
67
|
+
<a href="#" class="toc-link toc-title" id="toc-title-link">Contents</a>
|
|
68
|
+
<ul class="toc-list" id="toc-list">
|
|
69
|
+
<!-- TOC items will be populated by JavaScript -->
|
|
70
|
+
</ul>
|
|
71
|
+
</div>
|
|
72
|
+
</aside>
|
|
46
73
|
</div>
|
|
74
|
+
<!-- simple_webpage end main_content block -->
|
|
47
75
|
{% endblock main_content %}
|
|
48
|
-
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
{% block scripts_extra %}
|
|
79
|
+
{{ super() }}
|
|
80
|
+
<!-- simple_webpage begin scripts_extra block -->
|
|
81
|
+
<script>
|
|
82
|
+
{% include "components/toc_scripts.js.jinja" %}
|
|
83
|
+
{% include "components/tooltip_scripts.js.jinja" %}
|
|
84
|
+
</script>
|
|
85
|
+
<!-- simple_webpage end scripts_extra block -->
|
|
86
|
+
{% endblock scripts_extra %}
|
|
@@ -40,8 +40,9 @@
|
|
|
40
40
|
{% endblock page_content %}
|
|
41
41
|
<!-- tabbed_webpage end page_content block -->
|
|
42
42
|
|
|
43
|
-
<!-- tabbed_webpage begin scripts_extra block -->
|
|
44
43
|
{% block scripts_extra %}
|
|
44
|
+
<!-- tabbed_webpage begin scripts_extra block -->
|
|
45
|
+
<script>
|
|
45
46
|
function showTab(tabId, element) {
|
|
46
47
|
document.querySelectorAll(".tab-pane").forEach((tab) => {
|
|
47
48
|
tab.classList.add("hidden");
|
|
@@ -54,5 +55,6 @@
|
|
|
54
55
|
element.classList.add("tab-button-active");
|
|
55
56
|
element.classList.remove("tab-button-inactive");
|
|
56
57
|
}
|
|
58
|
+
</script>
|
|
59
|
+
<!-- tabbed_webpage end scripts_extra block -->
|
|
57
60
|
{% endblock scripts_extra %}
|
|
58
|
-
<!-- tabbed_webpage end scripts_extra block -->
|
kash/workspaces/workspaces.py
CHANGED
|
@@ -19,7 +19,11 @@ from kash.model.params_model import GLOBAL_PARAMS, RawParamValues
|
|
|
19
19
|
from kash.shell.output.shell_output import PrintHooks, cprint
|
|
20
20
|
from kash.utils.errors import FileNotFound, InvalidInput, InvalidState
|
|
21
21
|
from kash.utils.file_utils.ignore_files import IgnoreFilter, is_ignored_default
|
|
22
|
-
from kash.workspaces.workspace_dirs import
|
|
22
|
+
from kash.workspaces.workspace_dirs import (
|
|
23
|
+
check_strict_workspace_name,
|
|
24
|
+
is_global_ws_dir,
|
|
25
|
+
is_ws_dir,
|
|
26
|
+
)
|
|
23
27
|
from kash.workspaces.workspace_registry import WorkspaceInfo, get_ws_registry
|
|
24
28
|
|
|
25
29
|
if TYPE_CHECKING:
|
|
@@ -49,6 +53,11 @@ class Workspace(ABC):
|
|
|
49
53
|
def base_dir(self) -> Path:
|
|
50
54
|
"""The base directory for this workspace."""
|
|
51
55
|
|
|
56
|
+
@property
|
|
57
|
+
@abstractmethod
|
|
58
|
+
def assets_dir(self) -> Path:
|
|
59
|
+
"""The directory for this workspace's assets."""
|
|
60
|
+
|
|
52
61
|
|
|
53
62
|
def resolve_ws(name: str | Path) -> WorkspaceInfo:
|
|
54
63
|
"""
|