@fest-lib/fl-ui 0.1.11 → 0.1.13

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 CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@fest-lib/fl-ui",
3
- "description": "FL-UI components and services (fest-lib). Dev HTTPS: npm run dev https://localhost:8434/?suite=explorer (OPFS). HTTP-only: npm run dev:http.",
4
- "version": "0.1.11",
3
+ "description": "fest-lib FL.UI: windows, taskbar, app menu, Speed Dial (shapeless tiles). Dev: npm run dev",
4
+ "version": "0.1.13",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "sideEffects": true,
8
+ "imports": {
9
+ "#fl-ui/*": "./src/ui/*.ts"
10
+ },
8
11
  "engines": {
9
12
  "node": ">=20"
10
13
  },
@@ -1 +1,43 @@
1
- @layer tokens, base, layout, utilities, shells, shell, views, view, viewer, components, ux-layer, markdown, essentials, print, print-breaks, overrides;
1
+ /*
2
+ * Filename: layers.scss
3
+ * FullPath: modules/projects/fl.ui/src/styles/layers.scss
4
+ * Change date and time: 15.10.00_22.08.2026
5
+ * Reason for changes: Match veela `_layers.scss` so fl.ui never establishes a shorter competing prelude.
6
+ */
7
+
8
+ /*
9
+ * INVARIANT: Copy of `modules/projects/veela.css/src/scss/_layers.scss`.
10
+ * Change the veela file first, then keep this list identical.
11
+ * Hosts `@use` this file; they must not declare a second `@layer a, b, …` prelude.
12
+ */
13
+ @layer
14
+ ux-normalize,
15
+ tokens,
16
+ ux-tokens,
17
+ base,
18
+ ux-base,
19
+ layout,
20
+ ux-layout,
21
+ shells,
22
+ shell,
23
+ views,
24
+ view,
25
+ viewer,
26
+ components,
27
+ ux-components,
28
+ ux-layer,
29
+ ui-icon,
30
+ ui-icon-reset,
31
+ ux-file-manager,
32
+ ux-file-manager-content,
33
+ utilities,
34
+ ux-utilities,
35
+ theme,
36
+ ux-theme,
37
+ markdown,
38
+ essentials,
39
+ print,
40
+ print-breaks,
41
+ view-transitions,
42
+ overrides,
43
+ ux-overrides;
@@ -1,8 +1,7 @@
1
1
  // Incremental sheet: legacy host-wide native `button` + bare `input`/`select`/`textarea`.
2
2
  @use "./ui/native-host-button-chrome" as host;
3
3
  @use "./ui/forms-bare-host-elements" as bare;
4
-
5
- @layer tokens, base, layout, utilities, shells, shell, views, view, viewer, components, ux-layer, markdown, essentials, print, print-breaks, overrides;
4
+ @use "./layers";
6
5
 
7
6
  @layer components {
8
7
  button {
@@ -123,8 +123,8 @@
123
123
  $state-var: if(sass($variant == tonal): color.md3-var($state-role); else: color.md3-var($role));
124
124
 
125
125
  // Common CSS variable setup
126
- --md-button-bg: color-mix(in oklch, var(--surface-color, transparent) 90%, var(--on-surface-color, transparent));
127
- --md-button-on: var(--on-surface-color, currentColor);
126
+ --md-button-bg: color-mix(in oklch, var(--color-surface, var(--surface-color, transparent)) 90%, var(--color-on-surface, var(--on-surface-color, transparent)));
127
+ --md-button-on: var(--color-on-surface, var(--on-surface-color, currentColor));
128
128
  --md-button-outline-color: var(--border-color, transparent);
129
129
 
130
130
  // Variant-specific styles
@@ -138,8 +138,8 @@
138
138
  border: none;
139
139
  } @else {
140
140
  // filled, elevated, tonal
141
- background-color: var(--surface-color, var(--surface-color, transparent));
142
- color: var(--md-button-on, var(--on-surface-color, currentColor));
141
+ background-color: var(--color-surface, var(--surface-color, transparent));
142
+ color: var(--md-button-on, var(--color-on-surface, currentColor));
143
143
  border: none;
144
144
  }
145
145
 
@@ -6,8 +6,7 @@
6
6
  // Default off; opt in via `patch-global-native-controls.scss` / `loadFlUIGlobalNativeControlStyles()`.
7
7
  @use "./essentials-options" as eo;
8
8
  @use "./native-host-button-chrome" as hostbtn;
9
-
10
- @layer tokens, base, layout, utilities, shells, shell, views, view, viewer, components, ux-layer, markdown, essentials, print, print-breaks, overrides;
9
+ @use "../layers";
11
10
 
12
11
  @layer components {
13
12
  @if eo.$include-native-button-styles {
@@ -328,7 +327,7 @@
328
327
  * WHY: Launcher caption rows use `[data-layer="labels"]`; a global `span { aspect-ratio: 1/1 }` makes each pill as tall as its width (“box” tiles).
329
328
  * Square helpers apply only outside label captions (icon/grid tiles still use spans elsewhere).
330
329
  */
331
- .ui-ws-item:not([data-layer="labels"]) span {
330
+ .ui-ws-item:not([data-layer="labels"]) span:not(.ui-ws-item-caption) {
332
331
  pointer-events: none;
333
332
  aspect-ratio: 1 / 1;
334
333
  inline-size: fit-content;
@@ -374,7 +373,10 @@
374
373
  }
375
374
 
376
375
  @media screen {
377
- :root, :host, :scope {
376
+ ui-window-frame,
377
+ ui-modal,
378
+ .ui-grid-item,
379
+ .ctx-menu {
378
380
  --font-family: "InterVariable", "Inter", "Helvetica Neue", "Helvetica", "Calibri", "Roboto", ui-sans-serif, system-ui, -apple-system, Segoe UI, sans-serif;
379
381
  }
380
382
 
@@ -3,8 +3,8 @@
3
3
  //
4
4
  @layer ux-file-manager-content {
5
5
  /* Tighter actions track + explicit parent columns so subgrid rows align with the header */
6
- $row-grid: [icon] minmax(0px, 2.5rem) [name] minmax(0px, 1fr) [size] minmax(4.5rem, 6rem) [date] minmax(0px, 7.5rem) [actions] minmax(6.75rem, max-content);
7
- $row-grid-mobile: [icon] minmax(0px, 2.5rem) [name] minmax(0px, 1fr) [size] minmax(4.5rem, 6rem) [date] minmax(0px, 0px) [actions] minmax(6.75rem, max-content);
6
+ $row-grid: [icon] var(--ui-explorer-icon-track, 2rem) [name] minmax(0px, 1fr) [size] minmax(4.5rem, 6rem) [date] minmax(0px, 7.5rem) [actions] minmax(6.75rem, max-content);
7
+ $row-grid-mobile: [icon] var(--ui-explorer-icon-track, 2rem) [name] minmax(0px, 1fr) [size] minmax(4.5rem, 6rem) [date] minmax(0px, 0px) [actions] minmax(6.75rem, max-content);
8
8
 
9
9
  :host(ui-file-manager-content) {
10
10
  &, :where(*) {
@@ -76,7 +76,7 @@
76
76
  .fm-grid-rows {
77
77
  display: grid;
78
78
  grid-template-columns: subgrid;
79
- grid-auto-rows: 2.625rem;
79
+ grid-auto-rows: var(--ui-explorer-row-height, 2.625rem);
80
80
  grid-column: 1 / -1;
81
81
  align-content: start;
82
82
 
@@ -94,7 +94,7 @@
94
94
  z-index: 1;
95
95
 
96
96
  content-visibility: visible;
97
- contain-intrinsic-size: 1px 2.625rem;
97
+ contain-intrinsic-size: 1px var(--ui-explorer-row-height, 2.625rem);
98
98
  contain: none;
99
99
 
100
100
  //
@@ -110,7 +110,7 @@
110
110
  color: var(--color-on-surface);
111
111
 
112
112
  display: grid;
113
- grid-template-rows: minmax(0, 2.625rem) !important;
113
+ grid-template-rows: minmax(0, var(--ui-explorer-row-height, 2.625rem)) !important;
114
114
  grid-column: 1 / -1;
115
115
  order: var(--order, 1) !important;
116
116
  min-block-size: 0;
@@ -126,7 +126,7 @@
126
126
  cursor: pointer;
127
127
  pointer-events: auto;
128
128
  touch-action: manipulation;
129
- block-size: 2.625rem;
129
+ block-size: var(--ui-explorer-row-height, 2.625rem);
130
130
  user-drag: none;
131
131
  -webkit-user-drag: none;
132
132
 
@@ -146,8 +146,12 @@
146
146
  }
147
147
 
148
148
  ui-icon {
149
- inline-size: 1.25rem;
150
- block-size: 1.25rem;
149
+ --ui-icon-size: var(--ui-explorer-icon-size, 1.5rem);
150
+ --ui-icon-padding: 0px;
151
+ inline-size: var(--ui-icon-size);
152
+ block-size: var(--ui-icon-size);
153
+ min-inline-size: var(--ui-icon-size);
154
+ min-block-size: var(--ui-icon-size);
151
155
  flex-shrink: 0;
152
156
  place-content: center;
153
157
  place-items: center;
@@ -172,12 +176,12 @@
172
176
  background-color: color-mix(in oklab, var(--color-on-surface) 11%, transparent);
173
177
  }
174
178
  &:focus-visible {
175
- outline: 2px solid var(--color-primary, #3794ff);
179
+ outline: 2px solid var(--color-primary, #5a7fff);
176
180
  outline-offset: -2px;
177
181
  }
178
182
  }
179
183
 
180
- .c {
184
+ .c:not(.icon) {
181
185
  min-inline-size: 0;
182
186
  display: flex;
183
187
  flex-direction: row;
@@ -195,7 +199,33 @@
195
199
  block-size: auto;
196
200
  }
197
201
 
198
- .icon { grid-column: icon; place-content: center; place-items: center; }
202
+ .icon {
203
+ display: flex;
204
+ grid-column: icon;
205
+ place-content: center;
206
+ place-items: center;
207
+ overflow: visible;
208
+ flex-shrink: 0;
209
+ inline-size: 1.5rem;
210
+ block-size: 1.5rem;
211
+ min-inline-size: 1.5rem;
212
+ min-block-size: 1.5rem;
213
+ aspect-ratio: 1;
214
+
215
+ ui-icon,
216
+ img {
217
+ --ui-icon-size: var(--ui-explorer-icon-size, 1.5rem);
218
+ --ui-icon-padding: 0px;
219
+ inline-size: var(--ui-icon-size) !important;
220
+ block-size: var(--ui-icon-size) !important;
221
+ min-inline-size: var(--ui-icon-size) !important;
222
+ min-block-size: var(--ui-icon-size) !important;
223
+ max-inline-size: var(--ui-icon-size) !important;
224
+ max-block-size: var(--ui-icon-size) !important;
225
+ flex-shrink: 0;
226
+ object-fit: contain;
227
+ }
228
+ }
199
229
  .name { grid-column: name; inline-size: stretch; }
200
230
  .size {
201
231
  grid-column: size;
@@ -276,15 +306,19 @@
276
306
  }
277
307
 
278
308
  &:focus-visible {
279
- outline: 2px solid color-mix(in oklab, var(--color-primary, #3794ff) 55%, transparent);
309
+ outline: 2px solid color-mix(in oklab, var(--color-primary, #5a7fff) 55%, transparent);
280
310
  outline-offset: 1px;
281
311
  }
282
312
 
283
313
  ui-icon {
284
- inline-size: 1.0625rem;
285
- block-size: 1.0625rem;
286
- min-inline-size: 1.0625rem;
287
- min-block-size: 1.0625rem;
314
+ --ui-icon-size: var(--ui-explorer-action-icon-size, 1.15rem);
315
+ --ui-icon-padding: 0px;
316
+ inline-size: var(--ui-icon-size) !important;
317
+ block-size: var(--ui-icon-size) !important;
318
+ min-inline-size: var(--ui-icon-size) !important;
319
+ min-block-size: var(--ui-icon-size) !important;
320
+ max-inline-size: var(--ui-icon-size) !important;
321
+ max-block-size: var(--ui-icon-size) !important;
288
322
  }
289
323
  }
290
324
 
@@ -31,9 +31,13 @@
31
31
 
32
32
  background-color: var(--color-surface);
33
33
  color: var(--color-on-surface);
34
+ --ui-icon-size: var(--ui-explorer-icon-size, 1.5rem);
35
+ --ui-icon-padding: 0px;
36
+ --icon-color: var(--color-on-surface);
34
37
  }
35
38
 
36
39
  .fm-root {
40
+ position: relative;
37
41
  gap: 0;
38
42
  display: grid;
39
43
  grid-template-columns: [content-col] minmax(0px, 1fr);
@@ -79,7 +83,7 @@
79
83
  }
80
84
 
81
85
  input:focus-visible {
82
- box-shadow: 0 0 0 2px color-mix(in oklab, var(--color-primary, #3794ff) 45%, transparent);
86
+ box-shadow: 0 0 0 2px color-mix(in oklab, var(--color-primary, #5a7fff) 45%, transparent);
83
87
  }
84
88
 
85
89
  .btn {
@@ -98,8 +102,14 @@
98
102
  background: transparent;
99
103
 
100
104
  ui-icon {
101
- inline-size: 1.25rem;
102
- block-size: 1.25rem;
105
+ --ui-icon-size: var(--ui-explorer-icon-size, 1.5rem);
106
+ --ui-icon-padding: 0px;
107
+ inline-size: var(--ui-icon-size) !important;
108
+ block-size: var(--ui-icon-size) !important;
109
+ min-inline-size: var(--ui-icon-size) !important;
110
+ min-block-size: var(--ui-icon-size) !important;
111
+ max-inline-size: var(--ui-icon-size) !important;
112
+ max-block-size: var(--ui-icon-size) !important;
103
113
  flex-shrink: 0;
104
114
  }
105
115
  }
@@ -113,7 +123,7 @@
113
123
  }
114
124
 
115
125
  .btn:focus-visible {
116
- outline: 2px solid color-mix(in oklab, var(--color-primary, #3794ff) 55%, transparent);
126
+ outline: 2px solid color-mix(in oklab, var(--color-primary, #5a7fff) 55%, transparent);
117
127
  outline-offset: 1px;
118
128
  }
119
129
 
@@ -78,7 +78,7 @@
78
78
 
79
79
  //
80
80
  /* WHY: Exclude launcher label captions (`[data-layer="labels"]`) — `aspect-ratio: 1/1` on `span` mis-sizes ellipsis pills. */
81
- .ui-ws-item:not([data-layer="labels"]) span {
81
+ .ui-ws-item:not([data-layer="labels"]) span:not(.ui-ws-item-caption) {
82
82
  pointer-events: none;
83
83
  aspect-ratio: 1 / 1;
84
84
  inline-size: fit-content;
@@ -2,21 +2,28 @@
2
2
  // Loaded via adopted SpeedDial.scss — no dependency on `environment-shell/scss/*`.
3
3
  //
4
4
  // WHY: Shared demo mounts into `#app` with no intrinsic height; `%` + `min-block-size: 0` + abs
5
- // `.speed-dial-root` collapses the grid. Use `min-block-size: 100dvb` unless flex-mounted (`.wf-mounted-view`).
5
+ // `.speed-dial-root` collapses the grid. Use layout viewport (`100lvb` / `--lv-height`) so the
6
+ // Android IME overlays instead of squashing wallpaper + Speed Dial.
6
7
 
7
8
  $bp-desktop-min: 641px;
8
9
 
9
10
  @mixin home-view-host-styles {
10
- :where(body):has([data-view="home"]) {
11
+ :where(html):has(.speed-dial-root),
12
+ :where(html[data-cwsp-shell-role="launcher"]),
13
+ :where(body):has([data-view="home"]),
14
+ :where(body):has(.speed-dial-root) {
11
15
  margin: 0;
12
- min-block-size: 100dvb;
16
+ overflow: hidden;
17
+ min-block-size: var(--lv-height, 100lvb);
18
+ block-size: var(--lv-height, 100lvb);
19
+ max-block-size: var(--lv-height, 100lvb);
13
20
  }
14
21
 
15
22
  /* Typical view demo: `<main id="app">` + direct home root */
16
23
  :where(main, [role="main"]):has(> .view-home.env-home-workspace) {
17
24
  display: flex;
18
25
  flex-direction: column;
19
- min-block-size: 100dvb;
26
+ min-block-size: var(--lv-height, 100lvb);
20
27
  box-sizing: border-box;
21
28
  border: none;
22
29
  outline: none;
@@ -34,7 +41,7 @@ $bp-desktop-min: 641px;
34
41
  ) {
35
42
  display: flex;
36
43
  flex-direction: column;
37
- min-block-size: 100dvb;
44
+ min-block-size: var(--lv-height, 100lvb);
38
45
  box-sizing: border-box;
39
46
  border: none;
40
47
  outline: none;
@@ -72,21 +79,23 @@ $bp-desktop-min: 641px;
72
79
  justify-items: stretch;
73
80
  inline-size: 100%;
74
81
  min-inline-size: 0;
75
- min-block-size: 100dvb;
82
+ min-block-size: var(--lv-height, 100lvb);
76
83
  padding: 0;
77
84
  overflow: visible;
78
85
  background: transparent;
79
86
  box-sizing: border-box;
87
+ /* WHY: host stays non-hit for chrome stacking; #home must still receive paste/drop. */
80
88
  pointer-events: none;
81
89
 
82
90
  & > .speed-dial-root {
83
91
  position: absolute;
84
- inset: 0;
85
- inline-size: 100%;
86
- block-size: 100%;
87
- max-inline-size: 100%;
88
- max-block-size: 100%;
89
- pointer-events: none;
92
+ inset: 0 auto auto 0;
93
+ inline-size: var(--lv-width, 100%);
94
+ block-size: var(--lv-height, 100%);
95
+ max-inline-size: var(--lv-width, 100%);
96
+ max-block-size: var(--lv-height, 100%);
97
+ /* INVARIANT: desktop root must accept link drop/paste — do not leave pointer-events:none. */
98
+ pointer-events: auto;
90
99
  }
91
100
  }
92
101
 
@@ -120,9 +129,10 @@ $bp-desktop-min: 641px;
120
129
  .env-shell-workspace > .env-shell-home-mount > .view-home.env-home-workspace.wf-mounted-view > .speed-dial-root,
121
130
  .wf-view-host > .view-home.env-home-workspace.wf-mounted-view > .speed-dial-root {
122
131
  flex: 1 1 auto;
123
- min-block-size: 0;
124
- block-size: 100%;
125
- inline-size: 100%;
132
+ min-block-size: var(--lv-height, 100lvb);
133
+ block-size: var(--lv-height, 100lvb);
134
+ inline-size: var(--lv-width, 100%);
135
+ max-block-size: var(--lv-height, 100lvb);
126
136
  border-radius: 0 !important;
127
137
  outline: none !important;
128
138
  border: none !important;
@@ -174,6 +184,6 @@ $bp-desktop-min: 641px;
174
184
  background: transparent !important;
175
185
  backdrop-filter: none !important;
176
186
  -webkit-backdrop-filter: none !important;
177
- min-block-size: 100dvb;
187
+ min-block-size: var(--lv-height, 100lvb);
178
188
  }
179
189
  }
@@ -10,7 +10,7 @@
10
10
  @use "./shared" as *;
11
11
  @use "./states" as *;
12
12
  @use "./normalize" as *;
13
-
13
+ @use "./modal" as modal;
14
14
 
15
15
  @forward "./scrollbar";
16
16
  @forward "./layers";
@@ -20,3 +20,5 @@
20
20
  @forward "./bar";
21
21
  @forward "./home-host";
22
22
  @forward "./launcher-typography";
23
+
24
+ @include modal.transient-modal;
@@ -5,8 +5,7 @@
5
5
  * markdown-viewer.scss — optimized/refactored
6
6
  *
7
7
  * Стратегия:
8
- * - @layer: tokens markdown overrides print print-breaks
9
- * (каждый следующий слой побеждает предыдущий без !important)
8
+ * - @layer order: veela / fl.ui `layers.scss` SoT (do not declare a shorter prelude)
10
9
  * - light-dark() + color-scheme: inherit — вместо двух @media prefers-color-scheme
11
10
  * - @each по SCSS-map для heading-размеров (одно место правды)
12
11
  * - %img-align placeholder — устраняет 7-кратный повтор [align] / [width] / [height]
@@ -18,14 +17,14 @@
18
17
  * - !important только там, где реально нужно бороться с внешним JS-стилем
19
18
  */
20
19
 
20
+ @use "sass:map";
21
+ @use "sass:list";
22
+ @use "../layers";
21
23
  @use "../../../../veela.css/src/scss/core/misc/config" as config;
22
24
  @use "../../../../veela.css/src/scss/core/misc/tokens" as tokens;
23
25
  @use "../../../../veela.css/src/scss/core/misc/mixins" as mixins;
24
26
 
25
- @use "sass:map";
26
- @use "sass:list";
27
27
  @import "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";
28
- @layer tokens, markdown, overrides, print, print-breaks;
29
28
 
30
29
  /* ─── Animations ──────────────────────────────────────────────────────────── */
31
30
 
@@ -12,7 +12,7 @@
12
12
  place-content: center;
13
13
  place-items: center;
14
14
  padding: var(--space-xl);
15
- z-index: 9999;
15
+ z-index: var(--z-modal-backdrop, 400);
16
16
  line-height: normal;
17
17
  box-sizing: border-box;
18
18
  max-inline-size: min(100cqi, 100dvi);
@@ -41,8 +41,8 @@
41
41
  max-block-size: max(95dvb, 50rem);
42
42
 
43
43
  line-height: normal;
44
- background-color: var(--surface-color);
45
- color: var(--on-surface-color);
44
+ background-color: var(--color-surface, var(--surface-color));
45
+ color: var(--color-on-surface, var(--on-surface-color));
46
46
  padding: var(--padding-lg);
47
47
  padding-block-end: var(--space-md);
48
48
  border-radius: var(--radius-lg);
@@ -188,6 +188,7 @@
188
188
  background: transparent;
189
189
  border: none 0px transparent;
190
190
  outline: none 0px transparent;
191
+ flex-wrap: nowrap;
191
192
 
192
193
  //
193
194
  .modal-actions-right {
@@ -256,3 +257,53 @@
256
257
  }
257
258
  }
258
259
  }
260
+
261
+ /**
262
+ * Native-first helper styles. Kept separate from `modal()` because legacy
263
+ * `ui-modal` rules use containment that is unsafe for focusable dialog content.
264
+ */
265
+ @mixin transient-modal {
266
+ dialog.ui-modal-dialog {
267
+ inline-size: min(100% - 2rem, 36rem);
268
+ max-inline-size: calc(100dvi - 2rem);
269
+ max-block-size: calc(100dvb - 2rem);
270
+ margin: auto;
271
+ padding: 0;
272
+ border: 1px solid color-mix(in oklab, CanvasText 18%, transparent);
273
+ border-radius: var(--radius-lg, 1rem);
274
+ background: var(--modal-bg, Canvas);
275
+ color: var(--modal-fg, CanvasText);
276
+ box-shadow: var(--modal-shadow, 0 20px 60px rgb(0 0 0 / 0.42));
277
+ overflow: visible;
278
+
279
+ &::backdrop {
280
+ background: var(--modal-backdrop-bg, rgb(0 0 0 / 0.58));
281
+ backdrop-filter: blur(4px);
282
+ }
283
+ }
284
+
285
+ .ui-modal-backdrop {
286
+ position: fixed;
287
+ inset: 0;
288
+ z-index: var(--ui-modal-fallback-z, 2147483646);
289
+ display: grid;
290
+ place-items: center;
291
+ padding: 1rem;
292
+ background: var(--modal-backdrop-bg, rgb(0 0 0 / 0.58));
293
+ backdrop-filter: blur(4px);
294
+ pointer-events: auto;
295
+ }
296
+
297
+ .ui-modal-panel {
298
+ inline-size: min(100%, 36rem);
299
+ max-block-size: calc(100dvb - 2rem);
300
+ overflow: auto;
301
+ box-sizing: border-box;
302
+ padding: var(--modal-padding, 1.25rem);
303
+ border-radius: var(--modal-radius, var(--radius-lg, 1rem));
304
+ background: var(--modal-bg, Canvas);
305
+ color: var(--modal-fg, CanvasText);
306
+ box-shadow: var(--modal-shadow, 0 20px 60px rgb(0 0 0 / 0.42));
307
+ pointer-events: auto;
308
+ }
309
+ }
@@ -48,9 +48,9 @@
48
48
  direction: ltr !important;
49
49
 
50
50
  //
51
- // Cap by dynamic viewport and by JS visual viewport (--vv-* from fest/dom updateVP) for mobile browser chrome / keyboard.
52
- max-inline-size: min(100%, min(100cqi, 100dvi), var(--vv-width, 100dvi)) !important;
53
- max-block-size: min(100%, min(100cqb, 100dvb), var(--vv-height, 100dvb)) !important;
51
+ /* WHY: IME must overlay do not cap to shrinking `--vv-height` / `100dvb`. */
52
+ max-inline-size: min(100%, min(100cqi, 100lvi), var(--lv-width, 100lvi)) !important;
53
+ max-block-size: min(100%, min(100cqb, 100lvb), var(--lv-height, 100lvb)) !important;
54
54
 
55
55
  //
56
56
  /*outline-color: oklch(from var(--on-surface-color) l c h / 0.1);
@@ -1,8 +1,8 @@
1
1
  /*
2
2
  * Filename: _variables.scss
3
3
  * FullPath: modules/projects/fl.ui/src/styles/ui/_variables.scss
4
- * Change date and time: 16.25.00_31.07.2026
5
- * Reason for changes: Fallback --color-* via --u2-color-mod (token names kept).
4
+ * Change date and time: 15.16.00_22.08.2026
5
+ * Reason for changes: Fallback seed matches veela; emit inside @layer tokens so unlayered :root cannot beat SoT.
6
6
  */
7
7
 
8
8
  // Design tokens for fl.ui when veela is not loaded (minimal fallback).
@@ -26,20 +26,38 @@
26
26
  );
27
27
  }
28
28
 
29
+ @layer tokens {
29
30
  :root {
30
- --fl-ui-radius: 0.5rem;
31
- --fl-ui-gap: 0.75rem;
31
+ --fl-ui-radius: var(--radius-md, 0.5rem);
32
+ --fl-ui-gap: var(--space-md, 0.75rem);
32
33
 
33
34
  /*
34
- * NOTE: Standalone fl.ui fallback (used by _explorer.scss, _explorer-content.scss).
35
- * Canonical color-token source of truth is veela `core/misc/_tokens.scss`.
36
- * When veela is loaded, its `:root` `--color-*` / `--error-color` win by source
37
- * order; these remain as fallbacks for standalone fl.ui without veela.
35
+ * NOTE: Standalone fallback only. Same seed as veela SoT (`#5a9ec8`).
36
+ * INVARIANT: stay inside `@layer tokens` unlayered :root would beat veela.
38
37
  */
39
- --color-primary: #2e3a64;
38
+ --color-primary: #5a9ec8;
40
39
  --base-color: var(--color-primary);
41
40
  --color-surface: --u2-color-mod(var(--base-color), 920);
42
41
  --color-on-surface: --u2-color-mod(var(--base-color), 100);
43
42
  --color-on-surface-variant: --u2-color-mod(var(--base-color), 280);
44
- --error-color: #f87171;
43
+ --error-color: var(--color-error, #f87171);
44
+ --surface-color: var(--color-surface);
45
+ --on-surface-color: var(--color-on-surface);
46
+ --fl-surface: var(--color-surface);
47
+ --fl-on-surface: var(--color-on-surface);
48
+
49
+ /*
50
+ * COMPAT: same names as veela `@layer tokens`. Component styles consume
51
+ * these namespaced values; generic `--icon-*` variables stay local to
52
+ * the ui-icon shadow contract.
53
+ */
54
+ --ui-icon-size: 1.25rem;
55
+ --ui-icon-padding: 0px;
56
+ --ui-icon-tile-padding: 0.45rem;
57
+ --ui-window-icon-size: 0.95rem;
58
+ --ui-explorer-icon-size: 1.5rem;
59
+ --ui-explorer-icon-track: 2rem;
60
+ --ui-explorer-action-icon-size: 1.15rem;
61
+ --ui-explorer-row-height: 2.875rem;
62
+ }
45
63
  }
@@ -465,5 +465,6 @@
465
465
  }
466
466
  }
467
467
 
468
- // :root `--vv-width`, `--vv-height`, `--vv-offset-left`, `--vv-offset-top`, `--vv-scale`
469
- // are set by fest/dom `getAvailSize()` / `updateVP()` (see `whenAnyScreenChanges`).
468
+ // :root `--vv-*` is the visual viewport (IME may shrink it).
469
+ // `--lv-width` / `--lv-height` / `--view-height` stay on the layout viewport
470
+ // (fest/dom `getAvailSize()` / `updateVP()` — see `whenAnyScreenChanges`).
@@ -503,10 +503,10 @@
503
503
 
504
504
  @mixin window-frame-variables {
505
505
  // Window frame CSS custom properties — prefer veela/MD tokens over raw hex
506
- --ui-window-frame-bg: var(--fl-surface, var(--color-surface, --u2-color-mod(var(--base-color, #5a7fff), 40)));
507
- --ui-window-frame-color: var(--fl-on-surface, var(--color-on-surface, --u2-color-mod(var(--base-color, #5a7fff), 900)));
508
- --ui-window-frame-border-radius: var(--fl-radius-lg, 0.85rem);
509
- --ui-window-frame-shadow: var(--fl-shadow-xl, 0 20px 25px rgba(0, 0, 0, 0.1));
506
+ --ui-window-frame-bg: var(--color-surface, var(--fl-surface, --u2-color-mod(var(--base-color, #5a7fff), 40)));
507
+ --ui-window-frame-color: var(--color-on-surface, var(--fl-on-surface, --u2-color-mod(var(--base-color, #5a7fff), 900)));
508
+ --ui-window-frame-border-radius: var(--radius-lg, 0.75rem);
509
+ --ui-window-frame-shadow: var(--shadow-xl, var(--fl-shadow-xl, 0 20px 25px rgba(0, 0, 0, 0.1)));
510
510
  --ui-window-frame-titlebar-height: 2.5rem;
511
511
  --ui-window-frame-resize-handle-size: 8px;
512
512
  --ui-window-frame-min-width: 200px;