xtralab 0.12.5 → 0.13.0
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.
- package/package.json +1 -1
- package/style/base.css +1 -1
- package/style/chrome.css +1209 -0
- package/style/index.css +1 -0
- package/style/index.js +1 -0
- package/style/launcher.css +5 -2
- package/style/omnibox.css +17 -7
- package/style/tabs.css +9 -0
- package/style/walkthrough.css +3 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xtralab",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "An opinionated JupyterLab meta-package that bundles a curated set of extensions, ships a path-first file browser, renders jupyterlab-git's text, notebook and image diffs with its own viewers, and applies a quieter default workspace configuration.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jupyter",
|
package/style/base.css
CHANGED
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
padding: 2px 6px;
|
|
148
148
|
background-color: var(--jp-layout-color1);
|
|
149
149
|
border: 1px solid var(--jp-border-color2);
|
|
150
|
-
border-radius:
|
|
150
|
+
border-radius: 6px;
|
|
151
151
|
color: var(--jp-ui-font-color1);
|
|
152
152
|
font-family: var(--jp-ui-font-family);
|
|
153
153
|
font-size: var(--jp-ui-font-size1);
|
package/style/chrome.css
ADDED
|
@@ -0,0 +1,1209 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The chrome layer: a token-driven modernization pass over stock JupyterLab
|
|
3
|
+
* and Lumino chrome, so the app reads as a quiet native window rather than a
|
|
4
|
+
* paneled web app.
|
|
5
|
+
*
|
|
6
|
+
* The language, in one place:
|
|
7
|
+
* - one surface, separated by hairlines (--jp-border-color2), not the stock
|
|
8
|
+
* grid of grey-400 borders;
|
|
9
|
+
* - a radius scale: controls ~5-6px, popovers 8-10px, dialogs 12px;
|
|
10
|
+
* - soft large-blur shadows rebuilt from each theme's own shadow pieces;
|
|
11
|
+
* - state washes mixed from the theme's foreground (color-mix over
|
|
12
|
+
* --jp-ui-font-color1) instead of opaque layout-color blocks;
|
|
13
|
+
* - 100-150ms ease on hover state changes;
|
|
14
|
+
* - frosted translucency on transient overlays (menus, palette, omnibox).
|
|
15
|
+
*
|
|
16
|
+
* Two ground rules keep this safe:
|
|
17
|
+
* 1. Every color derives from the active theme's --jp-* tokens (or a
|
|
18
|
+
* color-mix over them), so the layer composes with JupyterLab
|
|
19
|
+
* Light/Dark and both Pierre themes. Theme-conditional rules key off
|
|
20
|
+
* body[data-jp-theme-light].
|
|
21
|
+
* 2. Lumino positions panels, tab bars, and menus with pixel math, so
|
|
22
|
+
* rules stick to paint-only properties (color, background,
|
|
23
|
+
* border-color, border-radius, box-shadow, opacity, transition).
|
|
24
|
+
* Where a stock border exists, only its color changes — widths stay.
|
|
25
|
+
*
|
|
26
|
+
* Token overrides live on `body`, not :root: themes define their tokens on
|
|
27
|
+
* :root in stylesheets loaded after this one, and inheritance from body
|
|
28
|
+
* beats :root regardless of load order.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/* stylelint-disable no-descending-specificity */
|
|
32
|
+
|
|
33
|
+
/* -----------------------------------------------------------------------------
|
|
34
|
+
| Design tokens
|
|
35
|
+
|---------------------------------------------------------------------------- */
|
|
36
|
+
|
|
37
|
+
body {
|
|
38
|
+
/* Controls-tier corner radius. Every styled button/input/select and the
|
|
39
|
+
FAST toolkit (which forwards this token to its shadow-DOM controls via
|
|
40
|
+
applyJupyterTheme -> controlCornerRadius) follows. */
|
|
41
|
+
--jp-border-radius: 6px;
|
|
42
|
+
|
|
43
|
+
/* Elevation ramp: fewer layers, larger blur, negative spread. Built from
|
|
44
|
+
the theme's own shadow color pieces, so each theme keeps its shadow
|
|
45
|
+
character (including Pierre light's deliberately faint shadows). */
|
|
46
|
+
--jp-elevation-z1: 0 1px 2px var(--jp-shadow-ambient-color);
|
|
47
|
+
--jp-elevation-z2:
|
|
48
|
+
0 1px 3px var(--jp-shadow-penumbra-color),
|
|
49
|
+
0 1px 2px var(--jp-shadow-ambient-color);
|
|
50
|
+
--jp-elevation-z4:
|
|
51
|
+
0 4px 12px -2px var(--jp-shadow-penumbra-color),
|
|
52
|
+
0 1px 3px var(--jp-shadow-ambient-color);
|
|
53
|
+
--jp-elevation-z6:
|
|
54
|
+
0 8px 24px -6px var(--jp-shadow-umbra-color),
|
|
55
|
+
0 2px 6px -2px var(--jp-shadow-ambient-color);
|
|
56
|
+
--jp-elevation-z8:
|
|
57
|
+
0 10px 28px -6px var(--jp-shadow-umbra-color),
|
|
58
|
+
0 3px 8px -3px var(--jp-shadow-ambient-color);
|
|
59
|
+
--jp-elevation-z12:
|
|
60
|
+
0 14px 32px -8px var(--jp-shadow-umbra-color),
|
|
61
|
+
0 4px 10px -4px var(--jp-shadow-ambient-color);
|
|
62
|
+
--jp-elevation-z16:
|
|
63
|
+
0 18px 40px -10px var(--jp-shadow-umbra-color),
|
|
64
|
+
0 5px 12px -5px var(--jp-shadow-ambient-color);
|
|
65
|
+
--jp-elevation-z20:
|
|
66
|
+
0 24px 48px -12px var(--jp-shadow-umbra-color),
|
|
67
|
+
0 6px 16px -6px var(--jp-shadow-ambient-color);
|
|
68
|
+
--jp-elevation-z24:
|
|
69
|
+
0 28px 56px -14px var(--jp-shadow-umbra-color),
|
|
70
|
+
0 8px 20px -8px var(--jp-shadow-ambient-color);
|
|
71
|
+
|
|
72
|
+
/* Toolbars separate with their existing border-bottom alone; the stock
|
|
73
|
+
omnidirectional 2px smudge shadow under every toolbar goes. */
|
|
74
|
+
--jp-toolbar-box-shadow: none;
|
|
75
|
+
--jp-toolbar-border-color: var(--jp-border-color2);
|
|
76
|
+
|
|
77
|
+
/* Inputs: rest on the theme's border ramp instead of the heavy
|
|
78
|
+
--jp-inverse-border-color (#757575 in both stock JupyterLab themes),
|
|
79
|
+
and focus with a soft outer ring instead of the inset blue glow. The
|
|
80
|
+
border-color swap to --jp-input-active-border-color that ships with
|
|
81
|
+
every stock :focus rule stays, giving the border + halo combo. */
|
|
82
|
+
--jp-input-border-color: var(--jp-border-color1);
|
|
83
|
+
--jp-input-box-shadow: 0 0 0 3px
|
|
84
|
+
color-mix(
|
|
85
|
+
in srgb,
|
|
86
|
+
var(--jp-input-active-border-color, var(--jp-brand-color1)) 22%,
|
|
87
|
+
transparent
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
/* Focused notebook/console cell: same outer-halo language, derived from
|
|
91
|
+
the theme's active cell border color (brand in all shipped themes). */
|
|
92
|
+
--jp-cell-editor-box-shadow: 0 0 0 3px
|
|
93
|
+
color-mix(
|
|
94
|
+
in srgb,
|
|
95
|
+
var(--jp-cell-editor-active-border-color, var(--jp-brand-color1)) 18%,
|
|
96
|
+
transparent
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
/* The stock JupyterLab themes color the ON state of switches ORANGE
|
|
100
|
+
(md-orange-900/700) — point it at the brand color instead (a no-op for
|
|
101
|
+
the Pierre themes). accent-color inherits into every native
|
|
102
|
+
checkbox/radio (dialogs, Settings editor, search filters). */
|
|
103
|
+
--jp-switch-true-position-color: var(--jp-brand-color1);
|
|
104
|
+
|
|
105
|
+
accent-color: var(--jp-brand-color1);
|
|
106
|
+
|
|
107
|
+
/* One selection language: brand-derived focused selection (JupyterLab
|
|
108
|
+
Light still ships a 2010-era solid lavender), neutral grey-out when
|
|
109
|
+
unfocused, light brand wash for multi-selected cells. Alpha values
|
|
110
|
+
layer correctly over the active-line highlight. */
|
|
111
|
+
--jp-editor-selected-focused-background: color-mix(
|
|
112
|
+
in srgb,
|
|
113
|
+
var(--jp-brand-color1) 22%,
|
|
114
|
+
transparent
|
|
115
|
+
);
|
|
116
|
+
--jp-editor-selected-background: color-mix(
|
|
117
|
+
in srgb,
|
|
118
|
+
var(--jp-ui-font-color1) 12%,
|
|
119
|
+
transparent
|
|
120
|
+
);
|
|
121
|
+
--jp-notebook-multiselected-color: color-mix(
|
|
122
|
+
in srgb,
|
|
123
|
+
var(--jp-brand-color1) 12%,
|
|
124
|
+
transparent
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
/* Dataframe row hover: brand wash instead of per-theme ad-hoc blues
|
|
128
|
+
(solid baby-blue in JupyterLab Light). */
|
|
129
|
+
--jp-rendermime-table-row-hover-background: color-mix(
|
|
130
|
+
in srgb,
|
|
131
|
+
var(--jp-brand-color1) 10%,
|
|
132
|
+
transparent
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
/* System monospace (SF Mono on macOS via ui-monospace), falling back to
|
|
136
|
+
the exact stock stack elsewhere. The prompt font follows so In[n]/Out[n]
|
|
137
|
+
match the editor. The terminal font is a JS setting, not CSS. */
|
|
138
|
+
--jp-code-font-family:
|
|
139
|
+
ui-monospace, 'SF Mono', sfmono-regular, menlo, consolas,
|
|
140
|
+
'DejaVu Sans Mono', monospace;
|
|
141
|
+
--jp-cell-prompt-font-family: var(--jp-code-font-family);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/*
|
|
145
|
+
* Light themes draw the chrome skeleton in a heavy mid-grey
|
|
146
|
+
* (--jp-border-color1 is #bdbdbd in JupyterLab Light). Step it down to the
|
|
147
|
+
* theme's own next ramp value for the hairline look. Dark themes keep their
|
|
148
|
+
* stronger line: shadows carry less depth information there, so color1
|
|
149
|
+
* stays for edge definition.
|
|
150
|
+
*/
|
|
151
|
+
body[data-jp-theme-light='true'] {
|
|
152
|
+
--jp-border-color1: var(--jp-border-color2);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/* The Pierre themes define neither focus-outline token, so stock
|
|
156
|
+
:focus-visible rules collapse to browser-default outlines there. Backfill
|
|
157
|
+
with the values JupyterLab Light uses. Scoped to the Pierre themes only:
|
|
158
|
+
JupyterLab Dark defines its own deliberately lighter #38a0f5 focus color,
|
|
159
|
+
which an unscoped body-level token would silently override. */
|
|
160
|
+
body[data-jp-theme-name='Pierre Light'],
|
|
161
|
+
body[data-jp-theme-name='Pierre Dark'] {
|
|
162
|
+
--jp-focus-outline-color: var(--jp-brand-color1);
|
|
163
|
+
--jp-focus-outline-width: 2px;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/*
|
|
167
|
+
* Slim quiet scrollbars everywhere. scrollbar-color inherits (crossing
|
|
168
|
+
* shadow-DOM boundaries), so the body rule recolors every scroll surface;
|
|
169
|
+
* scrollbar-width does NOT inherit, hence the separate descendant rule.
|
|
170
|
+
* In Chromium a non-auto value for either property disables
|
|
171
|
+
* ::-webkit-scrollbar styling on that element, which is also why the
|
|
172
|
+
* carve-outs below reset both to `auto`. body[data-jp-theme-light] matches
|
|
173
|
+
* every theme (the attribute is always present) and out-specifies core's
|
|
174
|
+
* optional [data-jp-theme-scrollbars='true'] rule. Elements that set their
|
|
175
|
+
* own scrollbar-color (e.g. core's .jp-scrollbar-tiny) keep it — a direct
|
|
176
|
+
* declaration always beats an inherited value.
|
|
177
|
+
*/
|
|
178
|
+
body[data-jp-theme-light] {
|
|
179
|
+
scrollbar-color: color-mix(in srgb, var(--jp-ui-font-color1) 28%, transparent)
|
|
180
|
+
transparent;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* The universal selector does not pierce shadow DOM, so @pierre internals
|
|
184
|
+
are untouched by the width rule. */
|
|
185
|
+
body[data-jp-theme-light],
|
|
186
|
+
body[data-jp-theme-light] * {
|
|
187
|
+
scrollbar-width: thin;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* Carve-out: the dock tab strip keeps its hand-built 2px webkit scrollbar
|
|
191
|
+
(style/tabs.css); element-level `auto` re-enables those rules. */
|
|
192
|
+
.lm-DockPanel-tabBar .lm-TabBar-content {
|
|
193
|
+
scrollbar-width: auto;
|
|
194
|
+
scrollbar-color: auto;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/* Carve-out: @pierre/trees (file browser) and @pierre/diffs (git diffs)
|
|
198
|
+
build their own hover-revealed webkit scrollbars inside shadow roots —
|
|
199
|
+
including a scrollbar-measuring element that feeds the trees gutter
|
|
200
|
+
width. Resetting the hosts to `auto` makes their shadow trees inherit
|
|
201
|
+
`auto` again, re-enabling both. The body[...] prefix out-specifies the
|
|
202
|
+
universal width rule above. */
|
|
203
|
+
body[data-jp-theme-light] file-tree-container,
|
|
204
|
+
body[data-jp-theme-light] diffs-container {
|
|
205
|
+
scrollbar-width: auto;
|
|
206
|
+
scrollbar-color: auto;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/* -----------------------------------------------------------------------------
|
|
210
|
+
| Window chrome: seams, menu bar, activity strips, status bar, splitters
|
|
211
|
+
|---------------------------------------------------------------------------- */
|
|
212
|
+
|
|
213
|
+
/* Structural hairlines: recolor the shell's skeleton borders (widths stay). */
|
|
214
|
+
#jp-top-panel {
|
|
215
|
+
border-bottom-color: var(--jp-border-color2);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.jp-LabShell[data-shell-mode='single-document'] #jp-menu-panel {
|
|
219
|
+
border-bottom-color: var(--jp-border-color2);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.jp-SideArea[data-side='left'] {
|
|
223
|
+
border-right-color: var(--jp-border-color2);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.jp-SideArea[data-side='right'] {
|
|
227
|
+
border-left-color: var(--jp-border-color2);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/*
|
|
231
|
+
* Re-assert the sidebar width floor over inline styles. Stock intends
|
|
232
|
+
* --jp-sidebar-min-width as the floor for sidebar stack children, but a
|
|
233
|
+
* widget moved into a sidebar (Move Widget To, or a drag) keeps the tiny
|
|
234
|
+
* inline min-width Lumino wrote while it lived in the dock — and inline
|
|
235
|
+
* beats the stylesheet, so the floor never engages for it. Combined with
|
|
236
|
+
* the shell saving the raw split sizes while a sidebar is collapsed
|
|
237
|
+
* (collapsed = ~0, unguarded upstream, unlike the down area's
|
|
238
|
+
* _lastDownAreaSize), a restored workspace then expands that sidebar to a
|
|
239
|
+
* 1px sliver. !important is the one thing that outranks an inline style;
|
|
240
|
+
* with the floor restored, even a zero saved size expands to a usable
|
|
241
|
+
* panel.
|
|
242
|
+
*/
|
|
243
|
+
#jp-left-stack > .lm-Widget,
|
|
244
|
+
#jp-right-stack > .lm-Widget {
|
|
245
|
+
min-width: var(--jp-sidebar-min-width) !important;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
#jp-down-stack {
|
|
249
|
+
border-bottom-color: var(--jp-border-color2);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* Borders framing each open document/panel in the dock. */
|
|
253
|
+
.lm-Widget.lm-DockPanel-widget,
|
|
254
|
+
.lm-TabPanel-stackedPanel.lm-TabPanel-stackedPanel {
|
|
255
|
+
border-color: var(--jp-border-color2);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* The 5px gutters between tiled editors show whatever paints behind the
|
|
259
|
+
dock panel — stock falls through to the body's layout-color3 (#bdbdbd in
|
|
260
|
+
JupyterLab Light). A quiet surface makes split views separate with a
|
|
261
|
+
soft seam instead of a dark bar. */
|
|
262
|
+
#jp-main-dock-panel {
|
|
263
|
+
background: var(--jp-layout-color2);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/*
|
|
267
|
+
* Menu bar: stock hover is an opaque grey block, and the OPEN item paints
|
|
268
|
+
* an opaque fill + 1px side borders + z6 shadow to fake a "tab connected
|
|
269
|
+
* to the menu". Rounded translucent highlights instead; the transparent
|
|
270
|
+
* 1px borders Lumino reserves keep their widths, so nothing shifts.
|
|
271
|
+
*/
|
|
272
|
+
.lm-MenuBar-item {
|
|
273
|
+
border-radius: 5px;
|
|
274
|
+
transition: background-color 120ms ease;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.jp-ThemedContainer .lm-MenuBar-item.lm-mod-active {
|
|
278
|
+
background: color-mix(in srgb, var(--jp-ui-font-color1) 7%, transparent);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.jp-ThemedContainer .lm-MenuBar.lm-mod-active .lm-MenuBar-item.lm-mod-active {
|
|
282
|
+
color: var(--jp-ui-font-color0);
|
|
283
|
+
background: color-mix(in srgb, var(--jp-ui-font-color1) 11%, transparent);
|
|
284
|
+
border-left-color: transparent;
|
|
285
|
+
border-right-color: transparent;
|
|
286
|
+
box-shadow: none;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.jp-LabShell[data-shell-mode='single-document']
|
|
290
|
+
.lm-MenuBar.lm-mod-active
|
|
291
|
+
.lm-MenuBar-item.lm-mod-active {
|
|
292
|
+
border-top-color: transparent;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/*
|
|
296
|
+
* Activity strips (left/right sidebar tab bars, in either orientation) and
|
|
297
|
+
* the down-area tab bar: stock draws them as bordered layout-color2 bands
|
|
298
|
+
* with separators between tabs and an opaque current tab — a classic
|
|
299
|
+
* tab-widget look. Flatten onto the window surface: hairline seams, muted
|
|
300
|
+
* icons that wake on hover, translucent washes, and a 2px brand accent on
|
|
301
|
+
* the current tab's outer edge. All separator overrides change border
|
|
302
|
+
* COLOR only, so the 1px widths Lumino measured stay.
|
|
303
|
+
*/
|
|
304
|
+
.jp-SideBar.lm-TabBar,
|
|
305
|
+
#jp-down-stack .lm-TabBar {
|
|
306
|
+
background: var(--jp-layout-color1);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* Hairline between the strip and its neighbor, all four placements. */
|
|
310
|
+
.jp-SideBar.lm-TabBar.jp-mod-left::after {
|
|
311
|
+
border-right-color: var(--jp-border-color2);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.jp-SideBar.lm-TabBar.jp-mod-right::after {
|
|
315
|
+
border-left-color: var(--jp-border-color2);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.jp-SideBar.lm-TabBar[data-side='top'] {
|
|
319
|
+
border-bottom-color: var(--jp-border-color2);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.jp-SideBar.lm-TabBar[data-side='bottom'] {
|
|
323
|
+
border-top-color: var(--jp-border-color2);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/* Separators off — vertical orientation… */
|
|
327
|
+
.jp-SideBar.lm-TabBar[data-orientation='vertical']
|
|
328
|
+
.lm-TabBar-tab
|
|
329
|
+
+ .lm-TabBar-tab,
|
|
330
|
+
.jp-SideBar.lm-TabBar[data-orientation='vertical']
|
|
331
|
+
.lm-TabBar-tab.lm-mod-current
|
|
332
|
+
+ .lm-TabBar-tab,
|
|
333
|
+
.jp-SideBar.lm-TabBar[data-orientation='vertical']
|
|
334
|
+
.lm-TabBar-tab
|
|
335
|
+
+ .lm-TabBar-tab.lm-mod-current {
|
|
336
|
+
border-top-color: transparent;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.jp-SideBar.lm-TabBar[data-orientation='vertical']
|
|
340
|
+
.lm-TabBar-tab.lm-mod-current:last-child {
|
|
341
|
+
border-bottom-color: transparent;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/* …and horizontal orientation. */
|
|
345
|
+
.jp-SideBar.lm-TabBar[data-orientation='horizontal']
|
|
346
|
+
.lm-TabBar-tab
|
|
347
|
+
+ .lm-TabBar-tab,
|
|
348
|
+
.jp-SideBar.lm-TabBar[data-orientation='horizontal']
|
|
349
|
+
.lm-TabBar-tab.lm-mod-current
|
|
350
|
+
+ .lm-TabBar-tab,
|
|
351
|
+
.jp-SideBar.lm-TabBar[data-orientation='horizontal']
|
|
352
|
+
.lm-TabBar-tab
|
|
353
|
+
+ .lm-TabBar-tab.lm-mod-current {
|
|
354
|
+
border-left-color: transparent;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.jp-SideBar.lm-TabBar[data-orientation='horizontal']
|
|
358
|
+
.lm-TabBar-tab.lm-mod-current:last-child {
|
|
359
|
+
border-right-color: transparent;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/* The current tab's "internal border override" pseudo-element paints an
|
|
363
|
+
opaque frame over the strip's edge hairline; keep the hairline running
|
|
364
|
+
continuously instead. */
|
|
365
|
+
.jp-SideBar .lm-TabBar-tab.lm-mod-current::after {
|
|
366
|
+
border-color: transparent;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/* Resting / hover / current fills. */
|
|
370
|
+
.jp-SideBar .lm-TabBar-tab:not(.lm-mod-current),
|
|
371
|
+
#jp-down-stack .lm-TabBar-tab:not(.lm-mod-current) {
|
|
372
|
+
background: transparent;
|
|
373
|
+
transition: background-color 120ms ease;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
.jp-SideBar .lm-TabBar-tab:hover:not(.lm-mod-current),
|
|
377
|
+
#jp-down-stack .lm-TabBar-tab:hover:not(.lm-mod-current) {
|
|
378
|
+
background: color-mix(in srgb, var(--jp-ui-font-color1) 6%, transparent);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.jp-SideBar .lm-TabBar-tab.lm-mod-current {
|
|
382
|
+
background: color-mix(in srgb, var(--jp-ui-font-color1) 4%, transparent);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/* Current-tab accent on the strip's outer edge (VS Code activity bar). */
|
|
386
|
+
.jp-SideBar.jp-mod-left .lm-TabBar-tab.lm-mod-current {
|
|
387
|
+
box-shadow: inset 2px 0 0 0 var(--jp-brand-color1);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.jp-SideBar.jp-mod-right .lm-TabBar-tab.lm-mod-current {
|
|
391
|
+
box-shadow: inset -2px 0 0 0 var(--jp-brand-color1);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
.jp-SideBar[data-side='top'] .lm-TabBar-tab.lm-mod-current {
|
|
395
|
+
box-shadow: inset 0 -2px 0 0 var(--jp-brand-color1);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.jp-SideBar[data-side='bottom'] .lm-TabBar-tab.lm-mod-current {
|
|
399
|
+
box-shadow: inset 0 2px 0 0 var(--jp-brand-color1);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/* Muted icons that wake on hover/selection. */
|
|
403
|
+
.jp-SideBar .lm-TabBar-tabIcon.jp-SideBar-tabIcon {
|
|
404
|
+
opacity: 0.7;
|
|
405
|
+
transition: opacity 120ms ease;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.jp-SideBar .lm-TabBar-tab:hover .lm-TabBar-tabIcon.jp-SideBar-tabIcon {
|
|
409
|
+
opacity: 0.95;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.jp-SideBar
|
|
413
|
+
.lm-TabBar-tab.lm-mod-current
|
|
414
|
+
.lm-TabBar-tabIcon.jp-SideBar-tabIcon {
|
|
415
|
+
opacity: 1;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/* Down-area tab bar: the current tab keeps its stock bordered-box
|
|
419
|
+
mechanics (translateY merge with the panel), on hairlines. */
|
|
420
|
+
#jp-down-stack > .lm-TabBar {
|
|
421
|
+
border-top-color: var(--jp-border-color2);
|
|
422
|
+
border-bottom-color: var(--jp-border-color2);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
#jp-down-stack > .lm-TabBar .lm-TabBar-tab.lm-mod-current {
|
|
426
|
+
border-color: var(--jp-border-color2);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/* Stock gives the first-child current tab its own higher-specificity
|
|
430
|
+
border-right rule; recolor it at matching specificity or the seam stays
|
|
431
|
+
on the stronger border-color1 in dark themes. */
|
|
432
|
+
#jp-down-stack > .lm-TabBar .lm-TabBar-tab.lm-mod-current:first-child {
|
|
433
|
+
border-right-color: var(--jp-border-color2);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/*
|
|
437
|
+
* Status bar: stock is a layout-color2 band with full-strength text, a
|
|
438
|
+
* hover that jumps to solid layout-color3, and a solid brand-blue block
|
|
439
|
+
* for the popup-open state. Window surface + hairline, muted text that
|
|
440
|
+
* wakes on hover, translucent fills. The hairline is an inset shadow, not
|
|
441
|
+
* a border: the bar is a border-box .lm-Widget and a border would eat into
|
|
442
|
+
* the 24px height its items fill.
|
|
443
|
+
*/
|
|
444
|
+
#jp-main-statusbar.jp-StatusBar-Widget {
|
|
445
|
+
background: var(--jp-layout-color1);
|
|
446
|
+
box-shadow: inset 0 1px 0 var(--jp-border-color2);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
.jp-StatusBar-Widget .jp-StatusBar-Item {
|
|
450
|
+
color: var(--jp-ui-font-color2);
|
|
451
|
+
border-radius: 4px;
|
|
452
|
+
transition:
|
|
453
|
+
background-color 120ms ease,
|
|
454
|
+
color 120ms ease;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/* Stock .jp-StatusBar-TextItem hardcodes font-color1; inherit the muted
|
|
458
|
+
item color so hover brightens both together. */
|
|
459
|
+
.jp-StatusBar-Widget .jp-StatusBar-Item .jp-StatusBar-TextItem {
|
|
460
|
+
color: inherit;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.jp-StatusBar-Widget .jp-StatusBar-Item.jp-mod-highlighted:hover {
|
|
464
|
+
color: var(--jp-ui-font-color1);
|
|
465
|
+
background-color: color-mix(
|
|
466
|
+
in srgb,
|
|
467
|
+
var(--jp-ui-font-color1) 8%,
|
|
468
|
+
transparent
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.jp-StatusBar-Widget .jp-StatusBar-Item.jp-mod-clicked {
|
|
473
|
+
color: var(--jp-ui-font-color1);
|
|
474
|
+
background-color: color-mix(in srgb, var(--jp-brand-color1) 22%, transparent);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
.jp-StatusBar-Widget .jp-StatusBar-Item.jp-mod-clicked:hover {
|
|
478
|
+
background-color: color-mix(in srgb, var(--jp-brand-color1) 30%, transparent);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.jp-StatusBar-Widget .jp-StatusBar-Item.jp-mod-clicked .jp-StatusBar-TextItem {
|
|
482
|
+
color: var(--jp-ui-font-color1);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/* The log-console chip marks its open state with jp-mod-selected (a solid
|
|
486
|
+
brand block with white text in stock, no Popup involved). The muting
|
|
487
|
+
rules above would leave grey text on that solid brand background; give
|
|
488
|
+
the state the same translucent-brand treatment as jp-mod-clicked. */
|
|
489
|
+
.jp-StatusBar-Widget .jp-StatusBar-Item.jp-mod-selected {
|
|
490
|
+
color: var(--jp-ui-font-color1);
|
|
491
|
+
background-color: color-mix(in srgb, var(--jp-brand-color1) 22%, transparent);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
.jp-StatusBar-Widget .jp-StatusBar-Item.jp-mod-selected .jp-StatusBar-TextItem {
|
|
495
|
+
color: var(--jp-ui-font-color1);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/* Status bar hover popups hardcode a Material shadow; fold them into the
|
|
499
|
+
themed ramp so they soften with everything else. */
|
|
500
|
+
.jp-StatusBar-HoverItem {
|
|
501
|
+
box-shadow: var(--jp-elevation-z6);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/*
|
|
505
|
+
* Resize handle affordance: the shell's split handles are 1px wide with an
|
|
506
|
+
* invisible 8px hit area; dock handles between tiled editors are 5px.
|
|
507
|
+
* Stock gives no hover feedback at all. Paint the accent on hover, delayed
|
|
508
|
+
* 150ms so it never flashes while the pointer crosses a boundary (the VS
|
|
509
|
+
* Code sash pattern). Background paint only.
|
|
510
|
+
*/
|
|
511
|
+
#jp-main-split-panel > .lm-SplitPanel-handle,
|
|
512
|
+
#jp-main-vsplit-panel > .lm-SplitPanel-handle {
|
|
513
|
+
background-color: transparent;
|
|
514
|
+
transition: background-color 120ms ease;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
#jp-main-split-panel > .lm-SplitPanel-handle:hover,
|
|
518
|
+
#jp-main-vsplit-panel > .lm-SplitPanel-handle:hover {
|
|
519
|
+
background-color: var(--jp-brand-color1);
|
|
520
|
+
transition-delay: 150ms;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/* Dock handles are 5px thick; a solid fill reads fat. Paint a 2px center
|
|
524
|
+
line on the existing ::after hit-area overlay and fade it in. */
|
|
525
|
+
#jp-main-dock-panel .lm-DockPanel-handle::after {
|
|
526
|
+
opacity: 0;
|
|
527
|
+
transition: opacity 120ms ease;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
#jp-main-dock-panel .lm-DockPanel-handle[data-orientation='horizontal']::after {
|
|
531
|
+
background: linear-gradient(
|
|
532
|
+
to right,
|
|
533
|
+
transparent calc(50% - 1px),
|
|
534
|
+
var(--jp-brand-color1) calc(50% - 1px),
|
|
535
|
+
var(--jp-brand-color1) calc(50% + 1px),
|
|
536
|
+
transparent calc(50% + 1px)
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
#jp-main-dock-panel .lm-DockPanel-handle[data-orientation='vertical']::after {
|
|
541
|
+
background: linear-gradient(
|
|
542
|
+
to bottom,
|
|
543
|
+
transparent calc(50% - 1px),
|
|
544
|
+
var(--jp-brand-color1) calc(50% - 1px),
|
|
545
|
+
var(--jp-brand-color1) calc(50% + 1px),
|
|
546
|
+
transparent calc(50% + 1px)
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
#jp-main-dock-panel .lm-DockPanel-handle:hover::after {
|
|
551
|
+
opacity: 1;
|
|
552
|
+
transition-delay: 150ms;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/* -----------------------------------------------------------------------------
|
|
556
|
+
| Document tabs
|
|
557
|
+
|---------------------------------------------------------------------------- */
|
|
558
|
+
|
|
559
|
+
/*
|
|
560
|
+
* Flat modern tab strip: slightly recessed surface, transparent inactive
|
|
561
|
+
* tabs with muted labels, inset hairline separators, and a current tab
|
|
562
|
+
* that merges with the toolbar below plus a rounded accent indicator.
|
|
563
|
+
* Composes with the adaptive tab widths in style/tabs.css (no width/flex/
|
|
564
|
+
* padding here). Doubled classes lift specificity over the stock rules in
|
|
565
|
+
* @jupyterlab/application/style/tabs.css without depending on load order.
|
|
566
|
+
*/
|
|
567
|
+
|
|
568
|
+
/* The strip: recessed surface with a hairline baseline drawn as an INSET
|
|
569
|
+
SHADOW (not a border, so the Lumino-measured bar height is unchanged).
|
|
570
|
+
The opaque current tab paints over it, producing the "active tab merges
|
|
571
|
+
with the toolbar below" seam for free. Dock tab bars only: the app's one
|
|
572
|
+
.lm-TabPanel-tabBar is the down-area bar, which draws real top/bottom
|
|
573
|
+
borders of its own — the inset baseline would double its bottom seam. */
|
|
574
|
+
.lm-DockPanel-tabBar[data-orientation='horizontal'] {
|
|
575
|
+
background: var(--jp-layout-color2);
|
|
576
|
+
box-shadow: inset 0 calc(-1 * var(--jp-border-width)) 0
|
|
577
|
+
var(--jp-border-color2);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/* Companion recolor for the thin tab-strip scrollbar (style/tabs.css):
|
|
581
|
+
let the strip surface show through instead of a layout-color1 track. */
|
|
582
|
+
.lm-DockPanel-tabBar .lm-TabBar-content::-webkit-scrollbar,
|
|
583
|
+
.lm-DockPanel-tabBar .lm-TabBar-content::-webkit-scrollbar-track {
|
|
584
|
+
background: transparent;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/* Inactive tabs: flat on the strip, muted label. border-color transparent
|
|
588
|
+
keeps the stock 1px border in the box model. */
|
|
589
|
+
.lm-DockPanel-tabBar .lm-TabBar-tab.lm-TabBar-tab,
|
|
590
|
+
.lm-TabPanel-tabBar .lm-TabBar-tab.lm-TabBar-tab {
|
|
591
|
+
color: var(--jp-ui-font-color2);
|
|
592
|
+
background: transparent;
|
|
593
|
+
border-color: transparent;
|
|
594
|
+
transition:
|
|
595
|
+
background-color 120ms ease,
|
|
596
|
+
color 120ms ease;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/* The stock per-tab bottom hairline is superseded by the strip's inset
|
|
600
|
+
baseline. Single class on purpose: this ties the stock base rule (same
|
|
601
|
+
specificity, we load later) while staying BELOW the stock :focus-visible
|
|
602
|
+
recolor, so the keyboard-focus underline still renders. */
|
|
603
|
+
.lm-DockPanel-tabBar .lm-TabBar-tab:not(.lm-mod-current)::after,
|
|
604
|
+
.lm-DockPanel-tabBar .lm-TabBar-addButton::after {
|
|
605
|
+
border-bottom-color: transparent;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/* Hover: a soft half-step toward the active surface. */
|
|
609
|
+
.lm-DockPanel-tabBar .lm-TabBar-tab.lm-TabBar-tab:hover:not(.lm-mod-current),
|
|
610
|
+
.lm-TabPanel-tabBar .lm-TabBar-tab.lm-TabBar-tab:hover:not(.lm-mod-current) {
|
|
611
|
+
color: var(--jp-ui-font-color1);
|
|
612
|
+
background: color-mix(
|
|
613
|
+
in srgb,
|
|
614
|
+
var(--jp-layout-color1) 45%,
|
|
615
|
+
var(--jp-layout-color2)
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/* Current tab: full-contrast surface + hairline sides. */
|
|
620
|
+
.lm-DockPanel-tabBar .lm-TabBar-tab.lm-TabBar-tab.lm-mod-current,
|
|
621
|
+
.lm-TabPanel-tabBar .lm-TabBar-tab.lm-TabBar-tab.lm-mod-current {
|
|
622
|
+
color: var(--jp-ui-font-color1);
|
|
623
|
+
background: var(--jp-layout-color1);
|
|
624
|
+
border-color: var(--jp-border-color2);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/* The stock edge-to-edge 2px brand bar on the app-level active tab is kept
|
|
628
|
+
as-is: it doubles as the tab's separator edge in the flat strip. */
|
|
629
|
+
|
|
630
|
+
/* Inset hairline separators between inactive tabs. Absolutely positioned
|
|
631
|
+
::before, so no layout impact. Current tabs are excluded because their
|
|
632
|
+
::before is the accent indicator. */
|
|
633
|
+
.lm-DockPanel-tabBar
|
|
634
|
+
.lm-TabBar-tab
|
|
635
|
+
+ .lm-TabBar-tab:not(.lm-mod-current, .jp-mod-current)::before {
|
|
636
|
+
content: '';
|
|
637
|
+
position: absolute;
|
|
638
|
+
top: 6px;
|
|
639
|
+
bottom: 7px;
|
|
640
|
+
left: 0;
|
|
641
|
+
width: var(--jp-border-width);
|
|
642
|
+
background: var(--jp-border-color2);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/* No separator immediately right of the current tab — its contrast edge is
|
|
646
|
+
the separator. Must come after the rule above. */
|
|
647
|
+
.lm-DockPanel-tabBar
|
|
648
|
+
.lm-TabBar-tab.lm-mod-current
|
|
649
|
+
+ .lm-TabBar-tab.lm-TabBar-tab::before {
|
|
650
|
+
content: none;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/* A dragged dock tab is always lm-mod-current (Lumino selects the pressed
|
|
654
|
+
tab on pointerdown, and dock tab bars disallow deselect), so the opaque
|
|
655
|
+
current-tab surface above already keeps its label legible during drags. */
|
|
656
|
+
|
|
657
|
+
/* The + button sits on the strip: drop its own layout-color2 box and give
|
|
658
|
+
it a rounded hover chip consistent with toolbar buttons. */
|
|
659
|
+
.lm-DockPanel-tabBar .lm-TabBar-addButton.lm-TabBar-addButton,
|
|
660
|
+
.lm-TabPanel-tabBar .lm-TabBar-addButton.lm-TabBar-addButton {
|
|
661
|
+
background-color: transparent;
|
|
662
|
+
border-radius: 5px;
|
|
663
|
+
transition: background-color 120ms ease;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
.lm-DockPanel-tabBar .lm-TabBar-addButton.lm-TabBar-addButton:hover,
|
|
667
|
+
.lm-TabPanel-tabBar .lm-TabBar-addButton.lm-TabBar-addButton:hover {
|
|
668
|
+
background-color: color-mix(
|
|
669
|
+
in srgb,
|
|
670
|
+
var(--jp-ui-font-color1) 8%,
|
|
671
|
+
transparent
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/*
|
|
676
|
+
* Tab close button: dimmed until the tab is hovered (45%, not 0, so the
|
|
677
|
+
* target stays discoverable), with a soft rounded chip when the icon
|
|
678
|
+
* itself is hovered. The chip is background + a 2px spread shadow of the
|
|
679
|
+
* same color, so the icon's box never changes and the adaptive tab widths
|
|
680
|
+
* stay stable. Dirty tabs render the unsaved dot inside the close-icon
|
|
681
|
+
* slot and stay at full opacity.
|
|
682
|
+
*/
|
|
683
|
+
.lm-DockPanel-tabBar .lm-TabBar-tab.lm-mod-closable > .lm-TabBar-tabCloseIcon {
|
|
684
|
+
opacity: 0.45;
|
|
685
|
+
border-radius: 4px;
|
|
686
|
+
transition:
|
|
687
|
+
opacity 100ms ease,
|
|
688
|
+
background-color 100ms ease,
|
|
689
|
+
box-shadow 100ms ease;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
.lm-DockPanel-tabBar
|
|
693
|
+
.lm-TabBar-tab.lm-mod-closable:hover
|
|
694
|
+
> .lm-TabBar-tabCloseIcon,
|
|
695
|
+
.lm-DockPanel-tabBar
|
|
696
|
+
.lm-TabBar-tab.lm-mod-closable.jp-mod-dirty
|
|
697
|
+
> .lm-TabBar-tabCloseIcon {
|
|
698
|
+
opacity: 1;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
.lm-DockPanel-tabBar
|
|
702
|
+
.lm-TabBar-tab.lm-mod-closable
|
|
703
|
+
> .lm-TabBar-tabCloseIcon:hover {
|
|
704
|
+
background-color: color-mix(
|
|
705
|
+
in srgb,
|
|
706
|
+
var(--jp-ui-font-color1) 12%,
|
|
707
|
+
transparent
|
|
708
|
+
);
|
|
709
|
+
box-shadow: 0 0 0 2px
|
|
710
|
+
color-mix(in srgb, var(--jp-ui-font-color1) 12%, transparent);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/* -----------------------------------------------------------------------------
|
|
714
|
+
| Toolbars
|
|
715
|
+
|---------------------------------------------------------------------------- */
|
|
716
|
+
|
|
717
|
+
/*
|
|
718
|
+
* Toolbar buttons are <jp-button appearance="stealth"> elements; the inner
|
|
719
|
+
* control is an exported shadow part, and document-level ::part() rules win
|
|
720
|
+
* over the component's internal FAST-palette fills — so hover chrome
|
|
721
|
+
* becomes theme-derived and consistent across every toolbar. The blue
|
|
722
|
+
* new-launcher CTA keeps its own accept-color hover (style/base.css).
|
|
723
|
+
*/
|
|
724
|
+
.jp-Toolbar .jp-ToolbarButtonComponent::part(control) {
|
|
725
|
+
border-radius: 5px;
|
|
726
|
+
transition: background-color 120ms ease;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
.jp-Toolbar
|
|
730
|
+
.jp-ToolbarButtonComponent:not(
|
|
731
|
+
[data-command='xtralab:new-launcher']
|
|
732
|
+
):hover::part(control) {
|
|
733
|
+
background: color-mix(in srgb, var(--jp-ui-font-color1) 8%, transparent);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/* Deprecated plain-button path still used by some extensions: same
|
|
737
|
+
treatment, mixed over its opaque resting fill. */
|
|
738
|
+
.jp-Toolbar button.jp-ToolbarButtonComponent {
|
|
739
|
+
border-radius: 5px;
|
|
740
|
+
transition: background-color 120ms ease;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
.jp-Toolbar button.jp-ToolbarButtonComponent:hover {
|
|
744
|
+
background: color-mix(
|
|
745
|
+
in srgb,
|
|
746
|
+
var(--jp-ui-font-color1) 8%,
|
|
747
|
+
var(--jp-layout-color1)
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/* -----------------------------------------------------------------------------
|
|
752
|
+
| Controls
|
|
753
|
+
|---------------------------------------------------------------------------- */
|
|
754
|
+
|
|
755
|
+
/* Dialog/action buttons ship letter-spacing 0.8px — a Material convention
|
|
756
|
+
that instantly dates the UI. Near-normal tracking, medium weight, and
|
|
757
|
+
the hover ease stock buttons lack. */
|
|
758
|
+
button.jp-mod-styled {
|
|
759
|
+
letter-spacing: 0.2px;
|
|
760
|
+
font-weight: 500;
|
|
761
|
+
transition:
|
|
762
|
+
background-color 120ms ease,
|
|
763
|
+
color 120ms ease;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
.jp-Button.jp-mod-minimal,
|
|
767
|
+
button.jp-ToolbarButtonComponent {
|
|
768
|
+
transition: background-color 120ms ease;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
/* Components that hardcode a radius and would not follow the token: */
|
|
772
|
+
|
|
773
|
+
/* Toolbar dropdowns (kernel switcher, cell type) pin border-radius: 0. */
|
|
774
|
+
.jp-HTMLSelect.jp-DefaultStyle select {
|
|
775
|
+
border-radius: var(--jp-border-radius);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/* Flat text buttons (running panel shutdown etc.) hardcode 2px. */
|
|
779
|
+
.jp-Button-flat {
|
|
780
|
+
border-radius: var(--jp-border-radius);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/* Stock inputs snap between states instantly. */
|
|
784
|
+
input.jp-mod-styled,
|
|
785
|
+
select.jp-mod-styled,
|
|
786
|
+
.jp-InputGroup input {
|
|
787
|
+
transition:
|
|
788
|
+
border-color 120ms ease,
|
|
789
|
+
box-shadow 120ms ease,
|
|
790
|
+
background-color 120ms ease;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
/* Stock switches animate at a floaty 0.4s; tighten. */
|
|
794
|
+
.jp-switch-track {
|
|
795
|
+
transition: background-color 150ms ease;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
.jp-switch-track::before {
|
|
799
|
+
transition: left 150ms ease;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
/* -----------------------------------------------------------------------------
|
|
803
|
+
| Menus
|
|
804
|
+
|---------------------------------------------------------------------------- */
|
|
805
|
+
|
|
806
|
+
/*
|
|
807
|
+
* Dropdown, context, and submenus: stock is square, hard-bordered
|
|
808
|
+
* (border-color1), with a Material z6 shadow, full-bleed highlights, and a
|
|
809
|
+
* mix-blend-mode separator that goes near-black on dark themes. Every
|
|
810
|
+
* JupyterLab menu carries .jp-ThemedContainer (MenuSvg adds it), giving a
|
|
811
|
+
* deterministic specificity bump over the stock .lm-Menu rules.
|
|
812
|
+
*
|
|
813
|
+
* The 5px side padding insets the item highlight macOS-style. Lumino
|
|
814
|
+
* measures the menu node after attach and before positioning, so the
|
|
815
|
+
* wider box is fully accounted for in its placement math.
|
|
816
|
+
*/
|
|
817
|
+
.lm-Menu.jp-ThemedContainer {
|
|
818
|
+
padding: 4px 5px;
|
|
819
|
+
border-radius: 8px;
|
|
820
|
+
border-color: color-mix(in srgb, var(--jp-border-color1) 55%, transparent);
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
/* Detach menubar dropdowns: stock pulls them up 2px to fuse with the bar.
|
|
824
|
+
Lumino positions the menu with an inline transform; this CSS `top`
|
|
825
|
+
offsets it. Lumino's max-height math does not know about the offset, so
|
|
826
|
+
a dropdown tall enough to hit the viewport bottom extends 3px past it —
|
|
827
|
+
only its bottom rounding is lost, and only on overfull menus. */
|
|
828
|
+
.lm-Menu.lm-MenuBar-menu.jp-ThemedContainer {
|
|
829
|
+
top: 3px;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/* The active-row highlight is painted on the row itself: table-row
|
|
833
|
+
backgrounds paint uniformly across the row, whereas per-cell painting
|
|
834
|
+
breaks — MenuSvg swaps the icon and submenu-caret cells for inline-block
|
|
835
|
+
elements whose boxes do not span the row (the icon cell is 0px tall).
|
|
836
|
+
The menu's 5px side padding keeps the highlight inset from the panel
|
|
837
|
+
edge; rounding is forfeited because border-radius does not render on
|
|
838
|
+
table rows. */
|
|
839
|
+
.lm-Menu.jp-ThemedContainer .lm-Menu-item.lm-mod-active {
|
|
840
|
+
background: color-mix(in srgb, var(--jp-ui-font-color1) 8%, transparent);
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
/* Muted shortcut hints, like every modern menu. */
|
|
844
|
+
.lm-Menu.jp-ThemedContainer .lm-Menu-itemShortcut {
|
|
845
|
+
color: var(--jp-ui-font-color3);
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
/* Stock separators multiply a light grey (mix-blend-mode), which goes
|
|
849
|
+
muddy on dark themes. Plain theme hairline instead. */
|
|
850
|
+
.lm-Menu.jp-ThemedContainer .lm-Menu-item[data-type='separator'] > div::after {
|
|
851
|
+
border-top-color: var(--jp-border-color2);
|
|
852
|
+
mix-blend-mode: normal;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
/* -----------------------------------------------------------------------------
|
|
856
|
+
| Command palette
|
|
857
|
+
|---------------------------------------------------------------------------- */
|
|
858
|
+
|
|
859
|
+
/* The modal palette as a floating panel. The hairline edge is a shadow
|
|
860
|
+
ring, not a border, so the CSS-positioned panel's size is unchanged. */
|
|
861
|
+
.jp-ModalCommandPalette.jp-ThemedContainer {
|
|
862
|
+
border-radius: 10px;
|
|
863
|
+
overflow: hidden;
|
|
864
|
+
box-shadow:
|
|
865
|
+
0 0 0 1px color-mix(in srgb, var(--jp-border-color1) 55%, transparent),
|
|
866
|
+
0 2px 6px var(--jp-shadow-ambient-color),
|
|
867
|
+
0 16px 48px -12px var(--jp-shadow-umbra-color);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
/* Rounded search field (keeps stock's inset border + focus treatment). */
|
|
871
|
+
.jp-ModalCommandPalette .lm-CommandPalette-wrapper {
|
|
872
|
+
border-radius: 6px;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/* Result rows: stock already insets them 4px in the modal variant.
|
|
876
|
+
(Section headers need no treatment: stock hides them entirely in the
|
|
877
|
+
modal palette.) */
|
|
878
|
+
.jp-ModalCommandPalette .lm-CommandPalette .lm-CommandPalette-item {
|
|
879
|
+
border-radius: 6px;
|
|
880
|
+
transition: background-color 120ms ease-out;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
/* -----------------------------------------------------------------------------
|
|
884
|
+
| Dialogs
|
|
885
|
+
|---------------------------------------------------------------------------- */
|
|
886
|
+
|
|
887
|
+
/* Dialog card: top of the radius scale, hairline ring for edge definition
|
|
888
|
+
on dark themes, soft themed elevation. The content node already clips
|
|
889
|
+
children with overflow: hidden. */
|
|
890
|
+
.jp-Dialog.jp-ThemedContainer .jp-Dialog-content {
|
|
891
|
+
border-radius: 12px;
|
|
892
|
+
box-shadow:
|
|
893
|
+
0 0 0 1px color-mix(in srgb, var(--jp-border-color1) 45%, transparent),
|
|
894
|
+
var(--jp-elevation-z20);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/* Smaller + semibold beats big-and-thin (stock is size3 / weight 400). */
|
|
898
|
+
.jp-Dialog.jp-ThemedContainer .jp-Dialog-header {
|
|
899
|
+
font-size: var(--jp-ui-font-size2);
|
|
900
|
+
font-weight: 600;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/* Frost the scrim slightly so the dialog pops without a darker tint.
|
|
904
|
+
Progressive enhancement over the theme's --jp-dialog-background. */
|
|
905
|
+
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
|
|
906
|
+
.jp-Dialog.jp-ThemedContainer {
|
|
907
|
+
-webkit-backdrop-filter: blur(3px);
|
|
908
|
+
backdrop-filter: blur(3px);
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
/* -----------------------------------------------------------------------------
|
|
913
|
+
| Completer and tooltip
|
|
914
|
+
|---------------------------------------------------------------------------- */
|
|
915
|
+
|
|
916
|
+
/* Same popover recipe as menus, but NOT frosted: translucency over code
|
|
917
|
+
hurts scan-reading of completions. The completer's JS sizing sets inline
|
|
918
|
+
width/max-height; radius and border-color change nothing it measures,
|
|
919
|
+
and overflow: hidden only clips paint (both children scroll internally). */
|
|
920
|
+
.jp-Completer.jp-ThemedContainer {
|
|
921
|
+
border-radius: 8px;
|
|
922
|
+
overflow: hidden;
|
|
923
|
+
border-color: color-mix(in srgb, var(--jp-border-color1) 55%, transparent);
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
.jp-Tooltip.jp-ThemedContainer {
|
|
927
|
+
border-radius: 8px;
|
|
928
|
+
border-color: color-mix(in srgb, var(--jp-border-color1) 55%, transparent);
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
/* -----------------------------------------------------------------------------
|
|
932
|
+
| Toast notifications
|
|
933
|
+
|---------------------------------------------------------------------------- */
|
|
934
|
+
|
|
935
|
+
/*
|
|
936
|
+
* Stock marks toast status with a 5px colored top strip. Rounded card with
|
|
937
|
+
* hairline border and a slim colored left accent instead — same five
|
|
938
|
+
* status tokens, modern grammar. Scoped under .jp-ThemedContainer (present
|
|
939
|
+
* on both the corner toast container and the notification-center popup) so
|
|
940
|
+
* these outrank react-toastify's lazy-loaded base CSS by specificity.
|
|
941
|
+
* (.Toastify__toast is react-toastify's own BEM class, hence the
|
|
942
|
+
* selector-class-pattern exemption.)
|
|
943
|
+
*/
|
|
944
|
+
|
|
945
|
+
/* stylelint-disable selector-class-pattern */
|
|
946
|
+
.jp-ThemedContainer .Toastify__toast {
|
|
947
|
+
padding: 8px 10px;
|
|
948
|
+
border: var(--jp-border-width) solid var(--jp-border-color2);
|
|
949
|
+
border-radius: 10px;
|
|
950
|
+
box-shadow:
|
|
951
|
+
0 1px 3px var(--jp-shadow-ambient-color),
|
|
952
|
+
0 8px 24px -6px var(--jp-shadow-penumbra-color);
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
.jp-ThemedContainer .Toastify__toast.jp-Notification-Toast-error {
|
|
956
|
+
border-top: var(--jp-border-width) solid var(--jp-border-color2);
|
|
957
|
+
border-left: 3px solid var(--jp-error-color1);
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
.jp-ThemedContainer .Toastify__toast.jp-Notification-Toast-warning {
|
|
961
|
+
border-top: var(--jp-border-width) solid var(--jp-border-color2);
|
|
962
|
+
border-left: 3px solid var(--jp-warn-color1);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
.jp-ThemedContainer .Toastify__toast.jp-Notification-Toast-info {
|
|
966
|
+
border-top: var(--jp-border-width) solid var(--jp-border-color2);
|
|
967
|
+
border-left: 3px solid var(--jp-info-color1);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
.jp-ThemedContainer .Toastify__toast.jp-Notification-Toast-success {
|
|
971
|
+
border-top: var(--jp-border-width) solid var(--jp-border-color2);
|
|
972
|
+
border-left: 3px solid var(--jp-success-color1);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
.jp-ThemedContainer .Toastify__toast.jp-Notification-Toast-in-progress {
|
|
976
|
+
border-top: var(--jp-border-width) solid var(--jp-border-color2);
|
|
977
|
+
border-left: 3px solid var(--jp-brand-color1);
|
|
978
|
+
}
|
|
979
|
+
/* stylelint-enable selector-class-pattern */
|
|
980
|
+
|
|
981
|
+
/* -----------------------------------------------------------------------------
|
|
982
|
+
| Document search overlay
|
|
983
|
+
|---------------------------------------------------------------------------- */
|
|
984
|
+
|
|
985
|
+
/* The find/replace overlay drops in as a hard-cornered flap with a
|
|
986
|
+
full-strength bordered input. Round its one exposed corner, float it on
|
|
987
|
+
the themed elevation ramp, and give the fields the app-wide soft-border
|
|
988
|
+
+ focus-ring treatment. */
|
|
989
|
+
.jp-DocumentSearch-overlay {
|
|
990
|
+
border-bottom-left-radius: 8px;
|
|
991
|
+
border-color: var(--jp-border-color2);
|
|
992
|
+
box-shadow: var(--jp-elevation-z4);
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
.jp-DocumentSearch-input-wrapper {
|
|
996
|
+
border-color: var(--jp-border-color1);
|
|
997
|
+
border-radius: 5px;
|
|
998
|
+
transition:
|
|
999
|
+
border-color 120ms ease,
|
|
1000
|
+
box-shadow 120ms ease;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
.jp-DocumentSearch-input-wrapper:focus-within {
|
|
1004
|
+
border-color: var(--jp-input-active-border-color, var(--jp-brand-color1));
|
|
1005
|
+
box-shadow: 0 0 0 3px
|
|
1006
|
+
color-mix(
|
|
1007
|
+
in srgb,
|
|
1008
|
+
var(--jp-input-active-border-color, var(--jp-brand-color1)) 22%,
|
|
1009
|
+
transparent
|
|
1010
|
+
);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
.jp-DocumentSearch-replace-button-wrapper {
|
|
1014
|
+
border-color: var(--jp-border-color1);
|
|
1015
|
+
border-radius: 5px;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
/* -----------------------------------------------------------------------------
|
|
1019
|
+
| Drag and drop
|
|
1020
|
+
|---------------------------------------------------------------------------- */
|
|
1021
|
+
|
|
1022
|
+
/* Drop-zone overlay: stock hardcodes a Material-blue tint that ignores the
|
|
1023
|
+
active theme, with a dashed marquee border. Soft brand wash, solid
|
|
1024
|
+
hairline, rounded. The overlay is an absolutely positioned
|
|
1025
|
+
pointer-events:none node whose geometry Lumino sets inline. */
|
|
1026
|
+
.lm-DockPanel-overlay {
|
|
1027
|
+
background: color-mix(in srgb, var(--jp-brand-color1) 10%, transparent);
|
|
1028
|
+
border: var(--jp-border-width) solid
|
|
1029
|
+
color-mix(in srgb, var(--jp-brand-color1) 55%, transparent);
|
|
1030
|
+
border-radius: 8px;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
/* Root-level zones use a 2px border in stock; normalize to the hairline. */
|
|
1034
|
+
.lm-DockPanel-overlay.lm-mod-root-top,
|
|
1035
|
+
.lm-DockPanel-overlay.lm-mod-root-left,
|
|
1036
|
+
.lm-DockPanel-overlay.lm-mod-root-right,
|
|
1037
|
+
.lm-DockPanel-overlay.lm-mod-root-bottom,
|
|
1038
|
+
.lm-DockPanel-overlay.lm-mod-root-center {
|
|
1039
|
+
border-width: var(--jp-border-width);
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
/* Drag ghosts (cursor-following overlay nodes attached to body): one
|
|
1043
|
+
rounded-card language instead of the stock brand top-border on tab
|
|
1044
|
+
ghosts and hardcoded black shadows on cell ghosts. */
|
|
1045
|
+
.lm-TabBar-tab.lm-mod-drag-image.lm-mod-drag-image {
|
|
1046
|
+
border-color: var(--jp-border-color2);
|
|
1047
|
+
border-radius: 6px;
|
|
1048
|
+
box-shadow:
|
|
1049
|
+
0 8px 24px -6px var(--jp-shadow-umbra-color),
|
|
1050
|
+
0 2px 8px -2px var(--jp-shadow-penumbra-color);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
.jp-dragImage {
|
|
1054
|
+
border-radius: 6px;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
.jp-dragImage-singlePrompt {
|
|
1058
|
+
box-shadow:
|
|
1059
|
+
0 1px 3px var(--jp-shadow-umbra-color),
|
|
1060
|
+
0 8px 24px var(--jp-shadow-penumbra-color);
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
.jp-dragImage-multipleBack {
|
|
1064
|
+
border-radius: 6px;
|
|
1065
|
+
box-shadow: 0 1px 3px var(--jp-shadow-umbra-color);
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
/* -----------------------------------------------------------------------------
|
|
1069
|
+
| Notebook cells and content
|
|
1070
|
+
|---------------------------------------------------------------------------- */
|
|
1071
|
+
|
|
1072
|
+
/* Rounded code-cell editor. Stock forces border-radius: 0; the element
|
|
1073
|
+
already has overflow: hidden, so the radius clips the CodeMirror
|
|
1074
|
+
background and active-line highlight cleanly. Console prompt cells share
|
|
1075
|
+
the class. */
|
|
1076
|
+
.jp-InputArea-editor {
|
|
1077
|
+
border-radius: 6px;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
/* Rendered markdown cells carry a border when active; match. */
|
|
1081
|
+
.jp-MarkdownOutput {
|
|
1082
|
+
border-radius: 6px;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
/* The Property-Inspector active-cell preview uses the same surface. */
|
|
1086
|
+
.jp-ActiveCellTool .jp-ActiveCellTool-CellContent {
|
|
1087
|
+
border-radius: 6px;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/* Command-mode focus ring joins the radius scale. */
|
|
1091
|
+
.jp-Notebook.jp-mod-commandMode .jp-Cell.jp-mod-active:focus-visible {
|
|
1092
|
+
border-radius: 6px;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
/* The 8px active-cell indicator bar becomes a full pill (radius = half the
|
|
1096
|
+
--jp-cell-collapser-width) and animates quietly. Width/flex untouched. */
|
|
1097
|
+
.jp-Collapser {
|
|
1098
|
+
border-radius: 4px;
|
|
1099
|
+
transition:
|
|
1100
|
+
background-color 120ms ease,
|
|
1101
|
+
opacity 120ms ease;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
/* Calmer collapser hover: translucent brand instead of Material elevation
|
|
1105
|
+
+ opacity flicker. */
|
|
1106
|
+
.jp-Notebook .jp-Cell .jp-Collapser:hover {
|
|
1107
|
+
opacity: 1;
|
|
1108
|
+
background: color-mix(in srgb, var(--jp-brand-color1) 55%, transparent);
|
|
1109
|
+
box-shadow: none;
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
.jp-Notebook .jp-Cell.jp-mod-active .jp-Collapser:hover {
|
|
1113
|
+
background: var(--jp-brand-color1);
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
/* In[n]/Out[n] two steps smaller with tabular figures (no [9]->[10]
|
|
1117
|
+
jitter). The line box is pinned to the height of one code line so the
|
|
1118
|
+
smaller text stays optically aligned with the first code line; the
|
|
1119
|
+
prompt column width is untouched. Markdown cells keep their own
|
|
1120
|
+
higher-specificity font-size from stock. */
|
|
1121
|
+
.jp-InputPrompt,
|
|
1122
|
+
.jp-OutputPrompt {
|
|
1123
|
+
font-size: calc(var(--jp-code-font-size) - 2px);
|
|
1124
|
+
line-height: calc(var(--jp-code-font-size) * var(--jp-code-line-height));
|
|
1125
|
+
font-variant-numeric: tabular-nums;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
/* Output-collapse hover overlay: drop the harsh inset inverse hairline,
|
|
1129
|
+
join the radius scale. */
|
|
1130
|
+
.jp-OutputArea-promptOverlay {
|
|
1131
|
+
border-radius: 6px;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
.jp-OutputArea-promptOverlay:hover {
|
|
1135
|
+
background: var(--jp-layout-color2);
|
|
1136
|
+
box-shadow: none;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
/* Markdown blockquote: hairline accent instead of the heavy 5px grey slab,
|
|
1140
|
+
quoted text stepped down to the secondary content color. */
|
|
1141
|
+
.jp-RenderedHTMLCommon blockquote {
|
|
1142
|
+
color: var(--jp-content-font-color2);
|
|
1143
|
+
border-left: 3px solid var(--jp-border-color1);
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
/* -----------------------------------------------------------------------------
|
|
1147
|
+
| Terminal
|
|
1148
|
+
|---------------------------------------------------------------------------- */
|
|
1149
|
+
|
|
1150
|
+
/* The terminal widget paints no background of its own, so the 8px body
|
|
1151
|
+
padding shows the dock panel surface as a mismatched frame. Match the
|
|
1152
|
+
xterm theme: 'inherit' reads --jp-layout-color0 in JS, and the forced
|
|
1153
|
+
modes mirror the #fff/#000 the xterm theme hardcodes (they key off the
|
|
1154
|
+
terminal's own theme setting, not the app theme). */
|
|
1155
|
+
.jp-Terminal[data-term-theme='inherit'] {
|
|
1156
|
+
background: var(--jp-layout-color0);
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
.jp-Terminal[data-term-theme='light'] {
|
|
1160
|
+
background: #fff;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
.jp-Terminal[data-term-theme='dark'] {
|
|
1164
|
+
background: #000;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
/* -----------------------------------------------------------------------------
|
|
1168
|
+
| Frosted overlays
|
|
1169
|
+
|---------------------------------------------------------------------------- */
|
|
1170
|
+
|
|
1171
|
+
/*
|
|
1172
|
+
* The signature: transient surfaces frost over the workspace, the way
|
|
1173
|
+
* native macOS menus do. Translucent theme-derived background + backdrop
|
|
1174
|
+
* blur, as progressive enhancement — without backdrop-filter support the
|
|
1175
|
+
* stock opaque backgrounds remain. Chromium clips backdrop-filter to
|
|
1176
|
+
* border-radius automatically. Deliberately excludes the completer
|
|
1177
|
+
* (readability over code) and dialogs (content surfaces stay solid).
|
|
1178
|
+
*/
|
|
1179
|
+
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
|
|
1180
|
+
/* Context menus + menubar dropdowns. The `background` shorthand also
|
|
1181
|
+
clears the menubar dropdown's scroll-hint gradients, which only appear
|
|
1182
|
+
on menus taller than the viewport — acceptable loss. */
|
|
1183
|
+
.lm-Menu.jp-ThemedContainer,
|
|
1184
|
+
.lm-MenuBar-menu.jp-ThemedContainer {
|
|
1185
|
+
background: color-mix(in srgb, var(--jp-layout-color0) 72%, transparent);
|
|
1186
|
+
-webkit-backdrop-filter: blur(20px) saturate(140%);
|
|
1187
|
+
backdrop-filter: blur(20px) saturate(140%);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
.jp-ModalCommandPalette.jp-ThemedContainer {
|
|
1191
|
+
background: color-mix(in srgb, var(--jp-layout-color0) 75%, transparent);
|
|
1192
|
+
-webkit-backdrop-filter: blur(24px) saturate(140%);
|
|
1193
|
+
backdrop-filter: blur(24px) saturate(140%);
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
/* Let the frost show through the palette's opaque inner layers (the
|
|
1197
|
+
input field keeps its own --jp-input-active-background). */
|
|
1198
|
+
.jp-ModalCommandPalette .lm-CommandPalette,
|
|
1199
|
+
.jp-ModalCommandPalette .lm-CommandPalette-search,
|
|
1200
|
+
.jp-ModalCommandPalette .lm-CommandPalette-content {
|
|
1201
|
+
background: transparent;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
.jp-xtralab-Omnibox-panel {
|
|
1205
|
+
background: color-mix(in srgb, var(--jp-layout-color1) 78%, transparent);
|
|
1206
|
+
-webkit-backdrop-filter: blur(24px) saturate(140%);
|
|
1207
|
+
backdrop-filter: blur(24px) saturate(140%);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
package/style/index.css
CHANGED
package/style/index.js
CHANGED
package/style/launcher.css
CHANGED
|
@@ -349,9 +349,11 @@
|
|
|
349
349
|
cursor: not-allowed;
|
|
350
350
|
}
|
|
351
351
|
|
|
352
|
+
/* border-color0: chrome.css remaps color1 onto color2 in light themes, so
|
|
353
|
+
a color1 hover would be identical to the resting color2 border there. */
|
|
352
354
|
.jp-xtralab-Launcher-agent:hover:not(:disabled) {
|
|
353
355
|
background-color: var(--jp-layout-color2);
|
|
354
|
-
border-color: var(--jp-border-
|
|
356
|
+
border-color: var(--jp-border-color0);
|
|
355
357
|
}
|
|
356
358
|
|
|
357
359
|
.jp-xtralab-Launcher-agent-icon {
|
|
@@ -438,9 +440,10 @@
|
|
|
438
440
|
font-size: var(--jp-ui-font-size0);
|
|
439
441
|
}
|
|
440
442
|
|
|
443
|
+
/* border-color0 for the same light-theme reason as the agent cards. */
|
|
441
444
|
.jp-xtralab-Launcher-mcp-copy:hover {
|
|
442
445
|
background-color: var(--jp-layout-color2);
|
|
443
|
-
border-color: var(--jp-border-
|
|
446
|
+
border-color: var(--jp-border-color0);
|
|
444
447
|
}
|
|
445
448
|
|
|
446
449
|
.jp-xtralab-Launcher-mcp-copy:focus-visible {
|
package/style/omnibox.css
CHANGED
|
@@ -30,8 +30,9 @@
|
|
|
30
30
|
/* Drop just below the top bar so it reads as a command-center dropdown. */
|
|
31
31
|
margin-top: calc(var(--jp-private-menubar-height, 28px) + 4px);
|
|
32
32
|
background: var(--jp-layout-color1);
|
|
33
|
-
border: var(--jp-border-width) solid
|
|
34
|
-
|
|
33
|
+
border: var(--jp-border-width) solid
|
|
34
|
+
color-mix(in srgb, var(--jp-border-color1) 55%, transparent);
|
|
35
|
+
border-radius: 10px;
|
|
35
36
|
box-shadow: var(--jp-elevation-z6);
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -50,13 +51,17 @@
|
|
|
50
51
|
color: var(--jp-ui-font-color3);
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
/* Side gutters float the active-row highlight inside the panel edge,
|
|
55
|
+
matching the menu/palette treatment; section headers and items shift
|
|
56
|
+
together so their left alignment is preserved. */
|
|
53
57
|
.jp-xtralab-Omnibox-results {
|
|
54
|
-
padding:
|
|
58
|
+
padding: 5px 6px;
|
|
55
59
|
overflow-y: auto;
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
.jp-xtralab-Omnibox-sectionHeader {
|
|
59
|
-
|
|
63
|
+
/* 8px + the results container's 6px gutter = the item rows' 14px inset. */
|
|
64
|
+
padding: 6px 8px 2px;
|
|
60
65
|
font-size: var(--jp-ui-font-size0);
|
|
61
66
|
font-weight: 600;
|
|
62
67
|
color: var(--jp-ui-font-color2);
|
|
@@ -68,14 +73,18 @@
|
|
|
68
73
|
display: flex;
|
|
69
74
|
gap: 8px;
|
|
70
75
|
align-items: center;
|
|
71
|
-
padding: 5px
|
|
76
|
+
padding: 5px 8px;
|
|
72
77
|
font-size: var(--jp-ui-font-size1);
|
|
73
78
|
color: var(--jp-ui-font-color1);
|
|
74
79
|
cursor: pointer;
|
|
80
|
+
border-radius: 6px;
|
|
81
|
+
transition: background-color 120ms ease-out;
|
|
75
82
|
}
|
|
76
83
|
|
|
84
|
+
/* Translucent foreground wash (not an opaque layout color) so the
|
|
85
|
+
highlight reads correctly on the frosted panel background. */
|
|
77
86
|
.jp-xtralab-Omnibox-item.jp-mod-active {
|
|
78
|
-
background: var(--jp-
|
|
87
|
+
background: color-mix(in srgb, var(--jp-ui-font-color1) 8%, transparent);
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
.jp-xtralab-Omnibox-itemIcon {
|
|
@@ -114,7 +123,8 @@
|
|
|
114
123
|
}
|
|
115
124
|
|
|
116
125
|
.jp-xtralab-Omnibox-empty {
|
|
117
|
-
|
|
126
|
+
/* 8px + the results container's 6px gutter = the item rows' 14px inset. */
|
|
127
|
+
padding: 14px 8px;
|
|
118
128
|
font-size: var(--jp-ui-font-size1);
|
|
119
129
|
color: var(--jp-ui-font-color2);
|
|
120
130
|
}
|
package/style/tabs.css
CHANGED
|
@@ -26,6 +26,15 @@
|
|
|
26
26
|
width: auto;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/* Breathing room between the label and the close icon. Fit-content tabs put
|
|
30
|
+
the icon flush against the label's last glyph (stock's fixed-width tabs
|
|
31
|
+
hide this with slack space), and the icon-hover chip in chrome.css extends
|
|
32
|
+
2px beyond the icon box into this gap. */
|
|
33
|
+
.lm-DockPanel-tabBar .lm-TabBar-tab .lm-TabBar-tabCloseIcon,
|
|
34
|
+
.lm-TabPanel-tabBar .lm-TabBar-tab .lm-TabBar-tabCloseIcon {
|
|
35
|
+
margin-left: 4px;
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
.lm-DockPanel-tabBar .lm-TabBar-content {
|
|
30
39
|
flex: 0 1 auto;
|
|
31
40
|
min-width: 0;
|
package/style/walkthrough.css
CHANGED
|
@@ -51,9 +51,11 @@
|
|
|
51
51
|
cursor: pointer;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/* border-color0: chrome.css remaps color1 onto color2 in light themes, so
|
|
55
|
+
a color1 hover would be identical to the resting color2 border there. */
|
|
54
56
|
.jp-xtralab-Walkthrough-jump:hover {
|
|
55
57
|
background-color: var(--jp-layout-color2);
|
|
56
|
-
border-color: var(--jp-border-
|
|
58
|
+
border-color: var(--jp-border-color0);
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
.jp-xtralab-Walkthrough-jump:focus-visible {
|