@keenmate/svelte-treeview 5.0.0-rc09 → 5.0.0-rc10

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.
Files changed (33) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +10 -7
  3. package/component-variables.manifest.json +6 -3
  4. package/dist/components/Node.svelte +6 -10
  5. package/dist/components/Tree.svelte +24 -0
  6. package/dist/components/Tree.svelte.d.ts +20 -2
  7. package/dist/components/TreeProvider.svelte +1 -0
  8. package/dist/constants.generated.d.ts +1 -1
  9. package/dist/constants.generated.js +1 -1
  10. package/dist/core/TreeController.svelte.d.ts +11 -0
  11. package/dist/core/TreeController.svelte.js +61 -2
  12. package/dist/ltree/ltree-node.svelte.js +2 -2
  13. package/dist/ltree/ltree.svelte.d.ts +1 -1
  14. package/dist/ltree/ltree.svelte.js +21 -5
  15. package/dist/ltree/types.d.ts +2 -0
  16. package/dist/styles/animations.css +17 -0
  17. package/dist/styles/{_base.css → base.css} +2 -0
  18. package/dist/styles/controls.css +4 -0
  19. package/dist/styles/dark-mode.css +139 -0
  20. package/dist/styles/{_drag-drop.css → drag-drop.css} +2 -6
  21. package/dist/styles/floating.css +5 -0
  22. package/dist/styles/{_loading.css → loading.css} +1 -5
  23. package/dist/styles/main.css +44 -37
  24. package/dist/styles/{_variables.css → variables.css} +56 -30
  25. package/dist/styles.css +939 -869
  26. package/package.json +6 -3
  27. /package/dist/styles/{_checkbox.css → checkbox.css} +0 -0
  28. /package/dist/styles/{_context-menu.css → context-menu.css} +0 -0
  29. /package/dist/styles/{_debug.css → debug.css} +0 -0
  30. /package/dist/styles/{_drop-zones.css → drop-zones.css} +0 -0
  31. /package/dist/styles/{_node.css → node.css} +0 -0
  32. /package/dist/styles/{_states.css → states.css} +0 -0
  33. /package/dist/styles/{_toggle-icons.css → toggle-icons.css} +0 -0
@@ -32,6 +32,8 @@
32
32
  .ltree-container {
33
33
  position: relative;
34
34
  outline: none;
35
+ background: var(--ltree-bg);
36
+ color: var(--ltree-body-color);
35
37
  }
36
38
 
37
39
  .ltree-virtual-scroll {
@@ -0,0 +1,4 @@
1
+ /* controls.css — no interactive form controls in this component.
2
+ (The checkbox lives in checkbox.css since it has substantial styling surface
3
+ and is a Tier-3 feature; this file is the canonical stub for buttons,
4
+ inputs, and other form chrome the tree doesn't render.) */
@@ -0,0 +1,139 @@
1
+ /* =============================================================================
2
+ DARK MODE / LIGHT MODE SUPPORT
3
+ =============================================================================
4
+ Belt-and-suspenders coverage: catches OS preference, page-level color-scheme,
5
+ framework theme classes, and per-instance data-theme overrides.
6
+
7
+ See guidelines/web-components/color-scheme.md for the full signals matrix.
8
+ Note: this component ships as Svelte (light DOM), so we use ancestor /
9
+ attribute selectors instead of the shadow-DOM :host-context() and :host()
10
+ forms in the canonical guideline.
11
+
12
+ Resolution precedence (highest specificity wins):
13
+ per-instance .ltree-container[data-theme]
14
+ → framework ancestor class
15
+ → page color-scheme via light-dark() in variables.css
16
+ → OS preference via @media (this file)
17
+ → hardcoded light defaults
18
+
19
+ Override surface: every block re-declares the same set of --ltree-* tokens.
20
+ Keep these blocks in sync — if a new themeable var is added in variables.css,
21
+ add it everywhere here too.
22
+ ============================================================================= */
23
+
24
+ /* ----------------------------------------------------------------------------
25
+ SHARED DARK VALUES
26
+ ----------------------------------------------------------------------------
27
+ Defined as a custom-property bundle on a private selector so the other dark
28
+ blocks can pull from one source of truth. Edits land in one place.
29
+ --------------------------------------------------------------------------- */
30
+
31
+ /* =============================================================================
32
+ SIGNAL #1 — OS preference (forced even when no color-scheme is declared)
33
+ ============================================================================= */
34
+ @media (prefers-color-scheme: dark) {
35
+ .ltree-container {
36
+ /* Every override chains through --base-* so themes that set a dark
37
+ variant of the canonical tokens (e.g. brand-forest's dark --base-main-bg)
38
+ win over the hardcoded dark fallbacks below. */
39
+ --ltree-bg: var(--base-main-bg, #1a1a1a);
40
+ --ltree-light: var(--base-main-bg, #1a1a1a);
41
+ --ltree-elevated-bg: var(--base-elevated-bg, #2b2b2b);
42
+ --ltree-border: var(--base-border-color, #3d3d3d);
43
+ --ltree-body-color: var(--base-text-color-1, #f5f5f5);
44
+ --ltree-node-path-color: var(--base-text-color-3, #a3a3a3);
45
+ --ltree-toggle-icon-color: var(--base-text-color-3, #a3a3a3);
46
+ --ltree-checkbox-border-color: var(--base-border-color, #5a5a5a);
47
+ --ltree-checkbox-bg: var(--base-input-bg, #1f1f1f);
48
+ --ltree-context-menu-bg: var(--base-dropdown-bg, var(--base-elevated-bg, var(--base-main-bg, #2b2b2b)));
49
+ --ltree-context-menu-shortcut-color: var(--base-text-color-4, #6b7280);
50
+ --ltree-context-menu-arrow-color: var(--base-text-color-4, #6b7280);
51
+ --ltree-context-menu-divider-label-color: var(--base-text-color-4, #6b7280);
52
+ --ltree-loading-bg: color-mix(in srgb, var(--base-main-bg, #1a1a1a) 80%, transparent);
53
+ --ltree-loading-color: var(--base-text-color-3, #a3a3a3);
54
+ --ltree-spinner-track: var(--base-border-color, #3d3d3d);
55
+ }
56
+ }
57
+
58
+ /* =============================================================================
59
+ SIGNAL #4 — Framework theme classes (Bootstrap 5.3+, Tailwind, generic)
60
+ =============================================================================
61
+ Safety net for frameworks that flip a theme class but don't set color-scheme
62
+ (Tailwind's `.dark`, hand-rolled toggles, older framework versions).
63
+ ============================================================================= */
64
+ [data-theme="dark"] .ltree-container,
65
+ [data-bs-theme="dark"] .ltree-container,
66
+ .dark .ltree-container {
67
+ --ltree-bg: var(--base-main-bg, #1a1a1a);
68
+ --ltree-light: var(--base-main-bg, #1a1a1a);
69
+ --ltree-elevated-bg: var(--base-elevated-bg, #2b2b2b);
70
+ --ltree-border: var(--base-border-color, #3d3d3d);
71
+ --ltree-body-color: var(--base-text-color-1, #f5f5f5);
72
+ --ltree-node-path-color: var(--base-text-color-3, #a3a3a3);
73
+ --ltree-toggle-icon-color: var(--base-text-color-3, #a3a3a3);
74
+ --ltree-checkbox-border-color: var(--base-border-color, #5a5a5a);
75
+ --ltree-checkbox-bg: var(--base-input-bg, #1f1f1f);
76
+ --ltree-context-menu-bg: var(--base-dropdown-bg, var(--base-elevated-bg, var(--base-main-bg, #2b2b2b)));
77
+ --ltree-context-menu-shortcut-color: var(--base-text-color-4, #6b7280);
78
+ --ltree-context-menu-arrow-color: var(--base-text-color-4, #6b7280);
79
+ --ltree-context-menu-divider-label-color: var(--base-text-color-4, #6b7280);
80
+ --ltree-loading-bg: color-mix(in srgb, var(--base-main-bg, #1a1a1a) 80%, transparent);
81
+ --ltree-loading-color: var(--base-text-color-3, #a3a3a3);
82
+ --ltree-spinner-track: var(--base-border-color, #3d3d3d);
83
+ }
84
+
85
+ /* =============================================================================
86
+ SIGNAL #5 — Per-instance override on a single tree
87
+ =============================================================================
88
+ Highest specificity: lets one tree theme differently from the surrounding
89
+ page. Wires through the `theme` prop forwarded by Tree.svelte.
90
+ ============================================================================= */
91
+ .ltree-container[data-theme="dark"] {
92
+ --ltree-bg: var(--base-main-bg, #1a1a1a);
93
+ --ltree-light: var(--base-main-bg, #1a1a1a);
94
+ --ltree-elevated-bg: var(--base-elevated-bg, #2b2b2b);
95
+ --ltree-border: var(--base-border-color, #3d3d3d);
96
+ --ltree-body-color: var(--base-text-color-1, #f5f5f5);
97
+ --ltree-node-path-color: var(--base-text-color-3, #a3a3a3);
98
+ --ltree-toggle-icon-color: var(--base-text-color-3, #a3a3a3);
99
+ --ltree-checkbox-border-color: var(--base-border-color, #5a5a5a);
100
+ --ltree-checkbox-bg: var(--base-input-bg, #1f1f1f);
101
+ --ltree-context-menu-bg: var(--base-dropdown-bg, var(--base-elevated-bg, var(--base-main-bg, #2b2b2b)));
102
+ --ltree-context-menu-shortcut-color: var(--base-text-color-4, #6b7280);
103
+ --ltree-context-menu-arrow-color: var(--base-text-color-4, #6b7280);
104
+ --ltree-context-menu-divider-label-color: var(--base-text-color-4, #6b7280);
105
+ --ltree-loading-bg: color-mix(in srgb, var(--base-main-bg, #1a1a1a) 80%, transparent);
106
+ --ltree-loading-color: var(--base-text-color-3, #a3a3a3);
107
+ --ltree-spinner-track: var(--base-border-color, #3d3d3d);
108
+ }
109
+
110
+ /* =============================================================================
111
+ SYMMETRIC LIGHT OVERRIDES — force light on a dark page
112
+ =============================================================================
113
+ When a consumer wants one tree to render light on an otherwise-dark page,
114
+ `data-theme="light"` (or the framework equivalent) restores the variables to
115
+ the original light defaults from variables.css.
116
+ ============================================================================= */
117
+ [data-theme="light"] .ltree-container,
118
+ [data-bs-theme="light"] .ltree-container,
119
+ .light .ltree-container,
120
+ .ltree-container[data-theme="light"] {
121
+ --ltree-bg: var(--base-main-bg, #ffffff);
122
+ --ltree-light: var(--base-main-bg, #f8f9fa);
123
+ --ltree-elevated-bg: var(--base-elevated-bg, #ffffff);
124
+ --ltree-border: var(--base-border-color, #dee2e6);
125
+ --ltree-body-color: var(--base-text-color-1, #212529);
126
+ --ltree-node-path-color: var(--base-text-color-3, #6c757d);
127
+ --ltree-toggle-icon-color: var(--base-text-color-3, #6c757d);
128
+ --ltree-checkbox-border-color: var(--base-border-color, #adb5bd);
129
+ --ltree-checkbox-bg: var(--base-input-bg, #ffffff);
130
+ --ltree-context-menu-bg: var(--base-dropdown-bg,
131
+ var(--base-elevated-bg,
132
+ var(--base-main-bg, #ffffff)));
133
+ --ltree-context-menu-shortcut-color: var(--base-text-color-4, #9ca3af);
134
+ --ltree-context-menu-arrow-color: var(--base-text-color-4, #9ca3af);
135
+ --ltree-context-menu-divider-label-color: var(--base-text-color-4, #9ca3af);
136
+ --ltree-loading-bg: color-mix(in srgb, var(--base-main-bg, #ffffff) 80%, transparent);
137
+ --ltree-loading-color: var(--base-text-color-3, #718096);
138
+ --ltree-spinner-track: var(--base-border-color, #e2e8f0);
139
+ }
@@ -35,7 +35,7 @@
35
35
  font-family: var(--ltree-font-family);
36
36
  pointer-events: none;
37
37
  z-index: 10000;
38
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
38
+ box-shadow: var(--tree-ghost-shadow);
39
39
  white-space: nowrap;
40
40
  max-width: 200px;
41
41
  overflow: hidden;
@@ -74,11 +74,7 @@
74
74
  box-shadow: var(--ltree-dragover-shadow) !important;
75
75
  }
76
76
 
77
- @keyframes bounce {
78
- 0%, 20%, 50%, 80%, 100% { transform: translateY(-50%); }
79
- 40% { transform: translateY(-60%); }
80
- 60% { transform: translateY(-40%); }
81
- }
77
+ /* (@keyframes bounce — moved to animations.css per canonical Tier-2 layout.) */
82
78
 
83
79
  /* Drag-over and drop validity states applied to .ltree-node-content */
84
80
  .ltree-node-content.ltree-drag-over {
@@ -0,0 +1,5 @@
1
+ /* floating.css — no Floating-UI-anchored chrome lives here.
2
+ (The context menu has its own substantial styling surface in context-menu.css
3
+ as a Tier-3 feature; the debug popup is statically positioned. This file is
4
+ the canonical stub for tooltips, dropdowns, popovers, and menus when more
5
+ floating surfaces are added.) */
@@ -24,11 +24,7 @@
24
24
  animation: ltree-spin 0.8s linear infinite;
25
25
  }
26
26
 
27
- @keyframes ltree-spin {
28
- to {
29
- transform: rotate(360deg);
30
- }
31
- }
27
+ /* (@keyframes ltree-spin — moved to animations.css per canonical Tier-2 layout.) */
32
28
 
33
29
  /* Progressive rendering loading indicator */
34
30
  .ltree-loading-more {
@@ -1,37 +1,44 @@
1
- /* =============================================================================
2
- @keenmate/svelte-treeview — Component Styles (entry point)
3
- =============================================================================
4
-
5
- File layout:
6
- _variables.css CSS custom properties at :root (theming surface)
7
- _base.css Tree container, virtual-scroll, layout foundation
8
- _node.css Node row, content, label, path
9
- _toggle-icons.css Toggle column + all 9 Lucide SVG icon classes
10
- _checkbox.css Custom-styled checkbox with indeterminate support
11
- _states.css Selection, highlight, scroll-highlight states
12
- _drag-drop.css Draggable cursor, ghost, drag-over, glow mode + arrows
13
- _drop-zones.css Drop zone overlays (around / above / below / wave / wave2)
14
- _context-menu.css Context menu, submenu, dividers
15
- _debug.css Debug info panel
16
- _loading.css Loading overlay + spinner
17
-
18
- Import order matters variables MUST be first; states / drag-drop / drop-zones
19
- reference variables; context-menu uses some of the same colors but does not
20
- depend on earlier rules.
21
-
22
- Build: lightningcss bundles this file (resolving the @import chain) into
23
- dist/styles.css during `npm run prepack`. Consumers import the bundled file:
24
- import '@keenmate/svelte-treeview/styles.css';
25
- */
26
-
27
- @import './_variables.css';
28
- @import './_base.css';
29
- @import './_node.css';
30
- @import './_toggle-icons.css';
31
- @import './_checkbox.css';
32
- @import './_states.css';
33
- @import './_drag-drop.css';
34
- @import './_drop-zones.css';
35
- @import './_context-menu.css';
36
- @import './_debug.css';
37
- @import './_loading.css';
1
+ /* ==============================================================================
2
+ @keenmate/svelte-treeview — MAIN ENTRY POINT
3
+ ==============================================================================
4
+ Cascade layer order (later = higher priority):
5
+ variables — :root { --ltree-* } declarations
6
+ component — base + feature rules
7
+ overrides — dark mode, framework themes, per-instance overrides
8
+
9
+ Consumer override contract:
10
+ - Any unlayered consumer rule beats every rule below.
11
+ - Any :root --base-* or --ltree-* declaration beats the variables layer.
12
+
13
+ BEM-ish convention:
14
+ .ltree-<element> — element
15
+ .ltree-<element>-<modifier> — state modifier
16
+ (Legacy class names predate strict BEM and are kept stable for back-compat.)
17
+
18
+ Build: lightningcss-cli bundles this file into dist/styles.css during
19
+ `npm run prepack`. Consumers import the bundled file:
20
+ import '@keenmate/svelte-treeview/styles.css';
21
+ */
22
+
23
+ @layer variables, component, overrides;
24
+
25
+ /* === SKELETON + CANONICAL CONCERNS (Tier 1 + Tier 2 — identical across the suite) === */
26
+ @import url('./variables.css') layer(variables);
27
+ @import url('./base.css') layer(component);
28
+ @import url('./controls.css') layer(component);
29
+ @import url('./floating.css') layer(component);
30
+ @import url('./states.css') layer(component);
31
+ @import url('./animations.css') layer(component);
32
+
33
+ /* === COMPONENT-SPECIFIC FEATURES (Tier 3 — alphabetized) === */
34
+ @import url('./checkbox.css') layer(component);
35
+ @import url('./context-menu.css') layer(component);
36
+ @import url('./debug.css') layer(component);
37
+ @import url('./drag-drop.css') layer(component);
38
+ @import url('./drop-zones.css') layer(component);
39
+ @import url('./loading.css') layer(component);
40
+ @import url('./node.css') layer(component);
41
+ @import url('./toggle-icons.css') layer(component);
42
+
43
+ /* === OVERRIDES === */
44
+ @import url('./dark-mode.css') layer(overrides);
@@ -1,18 +1,27 @@
1
1
  /* =============================================================================
2
- CSS CUSTOM PROPERTIES — :root level
2
+ CSS CUSTOM PROPERTIES — scoped to .ltree-container
3
3
  =============================================================================
4
4
  Every styling value is exposed as a --ltree-* custom property so end users
5
- can theme the component at runtime. Each variable follows this resolution
6
- chain:
7
-
8
- 1. End-user override: element { --ltree-x: red; }
9
- 2. KeenMate base token: --base-x (shared across @keenmate/* components)
10
- 3. Hardcoded default
11
-
12
- To override at runtime:
13
- .ltree-tree { --ltree-primary: #10b981; --ltree-node-font-size: 1.6rem; }
14
- Or globally for all KM components:
15
- :root { --base-accent-color: #10b981; }
5
+ can theme the component at runtime.
6
+
7
+ IMPORTANT: declarations are on .ltree-container (the tree's root element),
8
+ NOT on :root. This mirrors web-multiselect's :host-scoped pattern: var()
9
+ substitution happens AT the tree's own element, so an ancestor that sets
10
+ --base-accent-color (or any --base-*) actually re-tints the tree. Declaring
11
+ at :root would freeze the substituted value at the document root and ignore
12
+ any wrapper overrides.
13
+
14
+ Resolution chain (priority high low):
15
+ 1. Consumer rule targeting .ltree-container directly:
16
+ .my-wrap .ltree-container { --ltree-primary: red; }
17
+ 2. Consumer's --base-* set on any ancestor (including :root or a wrapper):
18
+ .my-wrap { --base-accent-color: red; }
19
+ 3. Hardcoded fallback inside the var() chain below.
20
+
21
+ Setting --ltree-* on a wrapper (not on .ltree-container itself) no longer
22
+ cascades into the tree, because .ltree-container has its own direct rule
23
+ for every --ltree-* token. To theme a subtree, prefer --base-* on the
24
+ wrapper, or write `.wrapper .ltree-container { --ltree-* }`.
16
25
 
17
26
  BASE SIZING UNIT
18
27
  ----------------
@@ -21,7 +30,7 @@
21
30
  make every dimension scale with document font-size (Pure-Admin pattern).
22
31
  ============================================================================= */
23
32
 
24
- :root {
33
+ .ltree-container {
25
34
  /* -------------------------------------------------------------------------
26
35
  BASE SIZING UNIT
27
36
  ------------------------------------------------------------------------- */
@@ -30,13 +39,23 @@
30
39
  /* -------------------------------------------------------------------------
31
40
  COLORS — theme integration via --base-* tokens
32
41
  Tinted variants are derived via color-mix(); no -rgb companion needed.
42
+
43
+ Color fallbacks use light-dark(<light>, <dark>) so consumers that declare
44
+ `html { color-scheme: light dark }` get OS-aware behavior automatically.
45
+ The brand accent (--base-accent-color) is treated as theme-independent —
46
+ both themes share the same primary.
33
47
  ------------------------------------------------------------------------- */
34
48
  --ltree-primary: var(--base-accent-color, #0d6efd);
35
- --ltree-success: var(--base-success-color, #198754);
36
- --ltree-danger: var(--base-danger-color, #dc3545);
37
- --ltree-light: var(--base-main-bg, #f8f9fa);
38
- --ltree-border: var(--base-border-color, #dee2e6);
39
- --ltree-body-color: var(--base-text-color-1, #212529);
49
+ --ltree-success: var(--base-success-color, light-dark(#198754, #2ea561));
50
+ --ltree-danger: var(--base-danger-color, light-dark(#dc3545, #f87c86));
51
+ --ltree-light: var(--base-main-bg, light-dark(#f8f9fa, #1a1a1a));
52
+ --ltree-elevated-bg: var(--base-elevated-bg, light-dark(#ffffff, #2b2b2b));
53
+ --ltree-border: var(--base-border-color, light-dark(#dee2e6, #3d3d3d));
54
+ --ltree-body-color: var(--base-text-color-1, light-dark(#212529, #f5f5f5));
55
+ /* Tree surface — painted on .ltree-container in base.css so the tree shows
56
+ a visible background without consumer wrapping. Override to `transparent`
57
+ to retain the pre-rc10 "no surface" behavior. */
58
+ --ltree-bg: var(--base-main-bg, light-dark(#ffffff, #1a1a1a));
40
59
 
41
60
  /* -------------------------------------------------------------------------
42
61
  TYPOGRAPHY — unitless --base-* multipliers × --ltree-rem
@@ -48,7 +67,7 @@
48
67
  --ltree-node-label-font-weight: var(--base-font-weight-medium, 500);
49
68
  --ltree-node-label-margin-right: calc(0.8 * var(--ltree-rem));
50
69
  --ltree-node-path-font-size: calc(var(--base-font-size-xs, 1.2) * var(--ltree-rem));
51
- --ltree-node-path-color: var(--base-text-color-3, #6c757d);
70
+ --ltree-node-path-color: var(--base-text-color-3, light-dark(#6c757d, #a3a3a3));
52
71
 
53
72
  /* -------------------------------------------------------------------------
54
73
  NODE LAYOUT
@@ -64,7 +83,7 @@
64
83
  ------------------------------------------------------------------------- */
65
84
  --ltree-toggle-icon-width: calc(2.0 * var(--ltree-rem));
66
85
  --ltree-toggle-icon-size: calc(1.6 * var(--ltree-rem));
67
- --ltree-toggle-icon-color: var(--base-text-color-3, #6c757d);
86
+ --ltree-toggle-icon-color: var(--base-text-color-3, light-dark(#6c757d, #a3a3a3));
68
87
  --ltree-toggle-icon-margin-right: calc(0.8 * var(--ltree-rem));
69
88
  --ltree-toggle-icon-transition: transform 0.2s;
70
89
 
@@ -73,9 +92,9 @@
73
92
  ------------------------------------------------------------------------- */
74
93
  --ltree-checkbox-size: calc(1.5 * var(--ltree-rem));
75
94
  --ltree-checkbox-border-width: 1.5px; /* hairline — does not scale */
76
- --ltree-checkbox-border-color: var(--base-border-color, #adb5bd);
95
+ --ltree-checkbox-border-color: var(--base-border-color, light-dark(#adb5bd, #5a5a5a));
77
96
  --ltree-checkbox-border-radius: calc(var(--base-border-radius-sm, 0.3) * var(--ltree-rem));
78
- --ltree-checkbox-bg: var(--base-input-bg, #fff);
97
+ --ltree-checkbox-bg: var(--base-input-bg, light-dark(#ffffff, #1f1f1f));
79
98
  --ltree-checkbox-checked-bg: var(--ltree-primary);
80
99
  --ltree-checkbox-checked-border-color: var(--ltree-primary);
81
100
  --ltree-checkbox-checkmark-color: var(--base-text-color-on-accent, #fff);
@@ -104,6 +123,7 @@
104
123
  /* Touch drag ghost */
105
124
  --tree-ghost-bg: color-mix(in srgb, var(--ltree-primary) 90%, transparent);
106
125
  --tree-ghost-color: #fff;
126
+ --tree-ghost-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
107
127
 
108
128
  /* -------------------------------------------------------------------------
109
129
  DROP ZONES (before / after / child) — pastel mode
@@ -148,10 +168,14 @@
148
168
  /* -------------------------------------------------------------------------
149
169
  CONTEXT MENU
150
170
  ------------------------------------------------------------------------- */
151
- --ltree-context-menu-bg: var(--base-dropdown-bg, #fff);
171
+ /* Dropdown chain: dropdown-bg → elevated-bg → main-bg → light-dark fallback.
172
+ Matches base-variables.md "Fallback chains — the four chained variables". */
173
+ --ltree-context-menu-bg: var(--base-dropdown-bg,
174
+ var(--base-elevated-bg,
175
+ var(--base-main-bg, light-dark(#ffffff, #2b2b2b))));
152
176
  --ltree-context-menu-border-color: var(--ltree-border);
153
177
  --ltree-context-menu-border-radius: calc(var(--base-border-radius-sm, 0.4) * var(--ltree-rem));
154
- --ltree-context-menu-shadow: var(--base-dropdown-box-shadow, 0 2px 10px rgba(0, 0, 0, 0.1));
178
+ --ltree-context-menu-shadow: var(--base-dropdown-box-shadow, 0 2px 10px rgba(0, 0, 0, 0.15));
155
179
  --ltree-context-menu-min-width: calc(15 * var(--ltree-rem));
156
180
  --ltree-context-menu-padding: calc(0.4 * var(--ltree-rem)) 0;
157
181
  --ltree-context-menu-item-padding: calc(0.8 * var(--ltree-rem)) calc(1.6 * var(--ltree-rem));
@@ -160,19 +184,21 @@
160
184
  --ltree-context-menu-item-hover-bg: var(--ltree-light);
161
185
  --ltree-context-menu-icon-size: calc(1.6 * var(--ltree-rem));
162
186
  --ltree-context-menu-icon-font-size: calc(var(--base-font-size-xs, 1.2) * var(--ltree-rem));
163
- --ltree-context-menu-shortcut-color: var(--base-text-color-4, #9ca3af);
187
+ --ltree-context-menu-shortcut-color: var(--base-text-color-4, light-dark(#9ca3af, #6b7280));
164
188
  --ltree-context-menu-shortcut-font-size: calc(var(--base-font-size-xs, 1.2) * var(--ltree-rem));
165
- --ltree-context-menu-arrow-color: var(--base-text-color-4, #9ca3af);
189
+ --ltree-context-menu-arrow-color: var(--base-text-color-4, light-dark(#9ca3af, #6b7280));
166
190
  --ltree-context-menu-divider-color: var(--ltree-border);
167
- --ltree-context-menu-divider-label-color: var(--base-text-color-4, #9ca3af);
191
+ --ltree-context-menu-divider-label-color: var(--base-text-color-4, light-dark(#9ca3af, #6b7280));
168
192
 
169
193
  /* -------------------------------------------------------------------------
170
194
  LOADING OVERLAY + SPINNER
171
195
  ------------------------------------------------------------------------- */
172
- --ltree-loading-bg: rgba(255, 255, 255, 0.8);
173
- --ltree-loading-color: var(--base-text-color-3, #718096);
196
+ /* Loading overlay: semi-transparent surface — use main-bg so it composites
197
+ correctly against both light and dark page backgrounds. */
198
+ --ltree-loading-bg: color-mix(in srgb, var(--base-main-bg, light-dark(#ffffff, #1a1a1a)) 80%, transparent);
199
+ --ltree-loading-color: var(--base-text-color-3, light-dark(#718096, #a3a3a3));
174
200
  --ltree-spinner-size: calc(3.2 * var(--ltree-rem));
175
- --ltree-spinner-track: var(--base-border-color, #e2e8f0);
201
+ --ltree-spinner-track: var(--base-border-color, light-dark(#e2e8f0, #3d3d3d));
176
202
  --ltree-spinner-color: var(--ltree-primary);
177
203
 
178
204
  /* -------------------------------------------------------------------------