@aceshooting/lyra-ui 24.1.0 → 25.0.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.
Files changed (206) hide show
  1. package/CHANGELOG.md +29 -20
  2. package/README.md +24 -28
  3. package/custom-elements.json +1 -1
  4. package/design-tokens.json +1 -1
  5. package/dist/components/agent-tools/activity-feed/activity-feed.styles.js +1 -1
  6. package/dist/components/agent-tools/task-list/task-list.styles.js +1 -1
  7. package/dist/components/agent-tools/thinking-panel/thinking-panel.styles.js +1 -1
  8. package/dist/components/conversation/chat-viewport/chat-viewport.class.js +1 -1
  9. package/dist/components/conversation/code-block/code-block.styles.js +1 -1
  10. package/dist/components/conversation/markdown/markdown.styles.js +1 -1
  11. package/dist/components/conversation/model-select/model-select.class.js +2 -1
  12. package/dist/components/conversation/model-select/model-select.styles.js +1 -1
  13. package/dist/components/conversation/selection-toolbar/selection-toolbar.styles.js +1 -1
  14. package/dist/components/conversation/voice-picker/voice-picker.class.js +2 -1
  15. package/dist/components/conversation/voice-picker/voice-picker.styles.js +1 -1
  16. package/dist/components/data/document-library/document-library.class.js +1 -1
  17. package/dist/components/data/table/table.class.d.ts +14 -3
  18. package/dist/components/data/table/table.class.js +8 -6
  19. package/dist/components/data/table/table.styles.js +1 -1
  20. package/dist/components/forms/color-picker/color-picker.class.js +2 -1
  21. package/dist/components/forms/color-picker/color-picker.styles.js +1 -1
  22. package/dist/components/forms/combobox/combobox.class.js +2 -1
  23. package/dist/components/forms/combobox/combobox.styles.js +1 -1
  24. package/dist/components/forms/date-picker/date-input.class.d.ts +3 -0
  25. package/dist/components/forms/date-picker/date-input.class.js +2 -1
  26. package/dist/components/forms/date-picker/date-input.styles.js +1 -1
  27. package/dist/components/forms/input/time-input.class.js +2 -1
  28. package/dist/components/forms/input/time-input.styles.js +1 -1
  29. package/dist/components/forms/locale-picker/locale-picker.class.d.ts +2 -1
  30. package/dist/components/forms/locale-picker/locale-picker.class.js +2 -1
  31. package/dist/components/forms/locale-picker/locale-picker.styles.js +1 -1
  32. package/dist/components/forms/otp-input/otp-input.class.js +1 -1
  33. package/dist/components/forms/select/select.class.js +2 -1
  34. package/dist/components/forms/select/select.styles.js +1 -1
  35. package/dist/components/forms/swatch-picker/swatch-picker.class.d.ts +6 -1
  36. package/dist/components/forms/swatch-picker/swatch-picker.class.js +1 -1
  37. package/dist/components/layout/app-rail/app-rail.styles.js +1 -1
  38. package/dist/components/layout/menu/menu.styles.js +1 -1
  39. package/dist/components/layout/menubar/menubar.styles.js +1 -1
  40. package/dist/components/layout/navigation-menu-item/navigation-menu-item.class.js +2 -2
  41. package/dist/components/layout/navigation-menu-item/navigation-menu-item.styles.js +1 -1
  42. package/dist/components/layout/scroller/scroller.styles.js +1 -1
  43. package/dist/components/media/av-player/av-player.styles.js +1 -1
  44. package/dist/components/media/image-viewer/image-viewer.styles.js +1 -1
  45. package/dist/components/media/map/map.class.d.ts +5 -2
  46. package/dist/components/media/map/map.class.js +4 -3
  47. package/dist/components/media/map/map.styles.js +1 -1
  48. package/dist/components/overlays/dialog/dialog.class.d.ts +1 -1
  49. package/dist/components/overlays/dialog/dialog.class.js +2 -1
  50. package/dist/components/overlays/dialog/dialog.styles.js +1 -1
  51. package/dist/components/overlays/overlay/overlay.styles.d.ts +1 -1
  52. package/dist/components/overlays/overlay/overlay.styles.js +1 -1
  53. package/dist/components/overlays/overlay/popover-glass.styles.d.ts +1 -0
  54. package/dist/components/overlays/overlay/popover-glass.styles.js +1 -0
  55. package/dist/components/overlays/overlay/popover.class.d.ts +11 -3
  56. package/dist/components/overlays/overlay/popover.class.js +1 -1
  57. package/dist/components/retrieval/knowledge-base/knowledge-base.class.js +1 -1
  58. package/dist/components/retrieval/source-list/source-list.styles.js +1 -1
  59. package/dist/components/utility/export-button/export-button.class.d.ts +1 -1
  60. package/dist/components/utility/export-button/export-button.class.js +2 -1
  61. package/dist/components/utility/export-button/export-button.styles.js +1 -1
  62. package/dist/components/utility/mention-popover/mention-popover.class.d.ts +1 -1
  63. package/dist/components/utility/mention-popover/mention-popover.class.js +2 -1
  64. package/dist/components/utility/mention-popover/mention-popover.styles.js +1 -1
  65. package/dist/components/viewers/document-compare/document-compare.styles.js +1 -1
  66. package/dist/components/viewers/document-preview/document-preview.class.js +1 -1
  67. package/dist/framework-types.d.ts +1 -1
  68. package/dist/internal/default-strings.generated.d.ts +1 -1
  69. package/dist/internal/default-strings.generated.js +1 -1
  70. package/dist/internal/glass-independent-root.styles.d.ts +2 -0
  71. package/dist/internal/glass-independent-root.styles.js +1 -0
  72. package/dist/internal/glass-scroll-layer.d.ts +1 -1
  73. package/dist/internal/glass-scroll-layer.js +1 -1
  74. package/dist/internal/glass-scroll-layer.styles.d.ts +2 -0
  75. package/dist/internal/glass-scroll-layer.styles.js +1 -0
  76. package/dist/internal/glass-surface.styles.d.ts +0 -2
  77. package/dist/internal/glass-surface.styles.js +1 -1
  78. package/dist/internal/localization-types.d.ts +1 -1
  79. package/dist/internal/localization.js +1 -1
  80. package/dist/internal/native-modal-carrier.js +2 -2
  81. package/dist/internal/package-metadata.d.ts +1 -1
  82. package/dist/internal/package-metadata.js +1 -1
  83. package/dist/internal/positioner.js +1 -1
  84. package/dist/internal/sizes.styles.js +1 -1
  85. package/dist/internal/specialist-tokens.styles.js +1 -1
  86. package/dist/internal/theme-token-types.d.ts +16 -0
  87. package/dist/internal/tokens/palette.styles.js +1 -1
  88. package/dist/internal/tokens.styles.js +1 -1
  89. package/dist/looks/material.css +1 -1
  90. package/dist/styles/design-tokens.css +1 -1
  91. package/dist/styles/tokens-root.css +1 -1
  92. package/dist/surfaces/glass.css +1 -1
  93. package/dist/theme/gemstones.d.ts +7 -0
  94. package/dist/theme/gemstones.js +1 -1
  95. package/dist/theme/looks/material.d.ts +1 -1
  96. package/dist/theme/looks/material.js +1 -1
  97. package/dist/theme/startup-resolution.d.ts +1 -0
  98. package/dist/theme/startup-resolution.js +1 -0
  99. package/dist/theme/style-ownership.js +1 -1
  100. package/dist/theme/theme-bootstrap.js +1 -1
  101. package/dist/theme/theme.d.ts +6 -21
  102. package/dist/theme/theme.js +1 -1
  103. package/dist/theme.css +1 -1
  104. package/dist/translations/am/data.js +1 -1
  105. package/dist/translations/ar/data.js +1 -1
  106. package/dist/translations/bho/data.js +1 -1
  107. package/dist/translations/bn/data.js +1 -1
  108. package/dist/translations/cs/data.js +1 -1
  109. package/dist/translations/da/data.js +1 -1
  110. package/dist/translations/de/data.js +1 -1
  111. package/dist/translations/el/data.js +1 -1
  112. package/dist/translations/es/data.js +1 -1
  113. package/dist/translations/fa/data.js +1 -1
  114. package/dist/translations/fa-AF/data.js +1 -1
  115. package/dist/translations/fi/data.js +1 -1
  116. package/dist/translations/fr/data.js +1 -1
  117. package/dist/translations/gu/data.js +1 -1
  118. package/dist/translations/ha/data.js +1 -1
  119. package/dist/translations/he/data.js +1 -1
  120. package/dist/translations/hi/data.js +1 -1
  121. package/dist/translations/hr/data.js +1 -1
  122. package/dist/translations/hu/data.js +1 -1
  123. package/dist/translations/id/data.js +1 -1
  124. package/dist/translations/ig/data.js +1 -1
  125. package/dist/translations/it/data.js +1 -1
  126. package/dist/translations/ja/data.js +1 -1
  127. package/dist/translations/jv/data.js +1 -1
  128. package/dist/translations/kk/data.js +1 -1
  129. package/dist/translations/kn/data.js +1 -1
  130. package/dist/translations/ko/data.js +1 -1
  131. package/dist/translations/ln/data.js +1 -1
  132. package/dist/translations/ml/data.js +1 -1
  133. package/dist/translations/mr/data.js +1 -1
  134. package/dist/translations/ms/data.js +1 -1
  135. package/dist/translations/my/data.js +1 -1
  136. package/dist/translations/nb/data.js +1 -1
  137. package/dist/translations/ne/data.js +1 -1
  138. package/dist/translations/nl/data.js +1 -1
  139. package/dist/translations/nn/data.js +1 -1
  140. package/dist/translations/om/data.js +1 -1
  141. package/dist/translations/or/data.js +1 -1
  142. package/dist/translations/pa/data.js +1 -1
  143. package/dist/translations/pcm/data.js +1 -1
  144. package/dist/translations/pl/data.js +1 -1
  145. package/dist/translations/pnb/data.js +1 -1
  146. package/dist/translations/ps/data.js +1 -1
  147. package/dist/translations/pt-BR/data.js +1 -1
  148. package/dist/translations/pt-PT/data.js +1 -1
  149. package/dist/translations/ro/data.js +1 -1
  150. package/dist/translations/ru/data.js +1 -1
  151. package/dist/translations/sd/data.js +1 -1
  152. package/dist/translations/sl/data.js +1 -1
  153. package/dist/translations/su/data.js +1 -1
  154. package/dist/translations/sv/data.js +1 -1
  155. package/dist/translations/sw/data.js +1 -1
  156. package/dist/translations/ta/data.js +1 -1
  157. package/dist/translations/te/data.js +1 -1
  158. package/dist/translations/th/data.js +1 -1
  159. package/dist/translations/tl/data.js +1 -1
  160. package/dist/translations/tr/data.js +1 -1
  161. package/dist/translations/uk/data.js +1 -1
  162. package/dist/translations/ur/data.js +1 -1
  163. package/dist/translations/uz/data.js +1 -1
  164. package/dist/translations/vi/data.js +1 -1
  165. package/dist/translations/yo/data.js +1 -1
  166. package/dist/translations/zh-CN/data.js +1 -1
  167. package/dist/translations/zh-TW/data.js +1 -1
  168. package/dist/translations/zu/data.js +1 -1
  169. package/llms/components/lr-date-input.md +1 -1
  170. package/llms/components/lr-date-picker.md +6 -0
  171. package/llms/components/lr-dialog.md +3 -0
  172. package/llms/components/lr-export-button.md +2 -0
  173. package/llms/components/lr-icon.md +1 -1
  174. package/llms/components/lr-locale-picker.md +7 -1
  175. package/llms/components/lr-map.md +7 -0
  176. package/llms/components/lr-mention-popover.md +3 -0
  177. package/llms/components/lr-model-select.md +3 -0
  178. package/llms/components/lr-navigation-menu.md +3 -0
  179. package/llms/components/lr-otp-input.md +3 -1
  180. package/llms/components/lr-popover.md +15 -5
  181. package/llms/components/lr-select.md +3 -0
  182. package/llms/components/lr-swatch-picker.md +17 -5
  183. package/llms/components/lr-table.md +14 -1
  184. package/llms/components/lr-voice-picker.md +3 -0
  185. package/llms/shared/native-styles-and-utilities.md +40 -0
  186. package/llms/shared/styles-and-tokens.md +257 -60
  187. package/llms/shared/testing-and-utilities.md +4 -1
  188. package/llms/shared.md +300 -61
  189. package/llms/tokens.md +82 -82
  190. package/locales.json +138 -138
  191. package/package.json +2 -2
  192. package/registrations.json +1 -1
  193. package/vscode-css-data.json +1 -1
  194. package/vscode-html-data.json +1 -1
  195. package/web-types.json +1 -1
  196. package/dist/components/agent-tools/run-events.js +0 -1
  197. package/dist/components/agent-tools/tool-param-form/tool-param-types.js +0 -1
  198. package/dist/components/forms/emoji-picker/emoji-types.js +0 -1
  199. package/dist/components/layout/dashboard-grid/layout-types.js +0 -1
  200. package/dist/components/layout/details/accordion-types.js +0 -1
  201. package/dist/components/viewers/viewer-diagnostics.js +0 -1
  202. package/dist/internal/localization-types.js +0 -1
  203. package/dist/internal/node-type-style.js +0 -1
  204. package/dist/internal/picker-value.js +0 -1
  205. package/dist/internal/shared-unions.js +0 -1
  206. package/dist/internal/stream-phase.js +0 -1
package/llms/shared.md CHANGED
@@ -881,6 +881,193 @@ See [Where an override actually reaches](#where-an-override-actually-reaches) be
881
881
  inheritance rules, including the one documented exception (per-component `--lr-<component>-*`
882
882
  hooks, layer 3, which do inherit through wrappers).
883
883
 
884
+ ### Lyra signature starter
885
+
886
+ Lyra's built-in profile is Shadcn, Glass, Emerald, System mode and comfortable density. Plain
887
+ component imports receive these defaults and a host-level Solid opt-out; `theme.css` provides the
888
+ full look/accent/mode resolver and the same profile for document scopes, including native chrome.
889
+ Explicit saved choices remain independent and win over missing or invalid fields. Use the existing style API to opt into Solid, the Lyra look, another accent or
890
+ mode; `accent: null` explicitly clears the accent, while `resetLyraStyle()` restores Emerald.
891
+
892
+ ```css
893
+ @layer lr-base, lr-theme, lr-theme-preset, lr-utilities, lr-overrides;
894
+ @layer lr-theme-preset.look, lr-theme-preset.density, lr-theme-preset.surface, lr-theme-preset.accent, lr-theme-preset.mode;
895
+ @import "@aceshooting/lyra-ui/theme.css";
896
+ @import "@aceshooting/lyra-ui/tokens-root.css";
897
+ ```
898
+
899
+ Keep both layer-order statements before these imports. Bundlers can hoist statements from imported
900
+ stylesheets; the declarations preserve the order when imports are flattened. See
901
+ [Cascade layers](#cascade-layers). Separate Shadcn, Glass and Emerald imports remain compatible,
902
+ but are unnecessary for this profile. Import other optional looks, accents and densities when
903
+ exposing those choices.
904
+
905
+ For first paint, run the synchronous `lyraThemeBootstrap` before blocking stylesheets, using the
906
+ [CSP-safe embedding or classic-script asset](#style-runtime--aceshootinglyra-uithemejs). It restores
907
+ valid saved axes and fills missing or invalid choices with the built-in profile. Keep the
908
+ application's legacy-key precedence in an application adapter, and retain saved Solid, Lyra,
909
+ custom accents, runtime looks, overrides and historical records. Do not reconstruct a saved record
910
+ from the normalized `parseLyraStyleRecord()` snapshot: it is not a lossless persistence format.
911
+ `getLyraStyle()` reads the same choices at runtime; user changes use `setLyraStyle()`. An application
912
+ Reset can call `resetLyraStyle()` and restore any separate application preferences. Selectable
913
+ alternate looks and an explicitly cleared accent require `theme.css`; the intrinsic component
914
+ profile does not replace that scope resolver.
915
+
916
+ Keep spotlights in application CSS, independent of the chosen control look. The public root-token
917
+ stylesheet makes this static recipe follow both light/dark mode and the current accent:
918
+
919
+ ```css
920
+ body { isolation: isolate; min-block-size: 100svh; background: var(--lr-color-surface); }
921
+ body::before {
922
+ content: '';
923
+ position: fixed;
924
+ inset: 0;
925
+ z-index: -1;
926
+ pointer-events: none;
927
+ background:
928
+ radial-gradient(ellipse 46rem 30rem at 8% 4%, color-mix(in srgb, var(--lr-color-brand) 16%, transparent), transparent 60%),
929
+ radial-gradient(ellipse 40rem 30rem at 96% 22%, color-mix(in srgb, var(--lr-color-brand) 12%, transparent), transparent 58%),
930
+ radial-gradient(ellipse 44rem 32rem at 78% 96%, color-mix(in srgb, var(--lr-color-brand) 9%, transparent), transparent 60%),
931
+ var(--lr-color-surface);
932
+ }
933
+ html[data-lr-contrast='more'] body::before { background: var(--lr-color-surface); }
934
+ @media (forced-colors: active) { body::before { background: Canvas; } }
935
+ ```
936
+
937
+ Keep an existing application's multicolor spotlight palette when adopting a control look. For
938
+ example, an accent/violet/pink canvas should retain all three gradient colors across Lyra, Shadcn,
939
+ and Material; changing `look` must not replace those colors with the same-accent starter above.
940
+ Keep application background rules outside look selectors, while letting mode and accent update
941
+ their own inputs.
942
+
943
+ These are decorative application backgrounds, not an `accentBackground` value: that style field
944
+ accepts absolute colors used as contrast reference surfaces, not gradients or image URLs. Use
945
+ semantic surface/text pairings for content and keep the decorative layer behind it.
946
+
947
+ Use the existing [gemstoneAccentPicker composition](../components/lr-swatch-picker.md#gemstoneaccentpicker--the-signature-accent-selector),
948
+ with its localized caption, nine canonical gemstones, and shared selected-glyph treatment. Keep
949
+ `--lr-swatch-picker-wrap: nowrap`: desktop hit size `1.75rem` and gap `.25rem`; at widths up to
950
+ `30rem`, hit size `1.5rem` and gap `.125rem` (28/4px and 24/2px at a 16px root). Leave its fill size
951
+ unset. Bound the palette to the viewport and provide horizontal overflow for unusually narrow
952
+ allocations or enlarged text; keyboard focus must bring every swatch into view. Do not shrink
953
+ below the component's 24px floor or replace its Arrow/Home/End and RTL behavior. For an independent
954
+ Shine preference, set `--lr-gemstone-selected-animation: none` on the scope shared by the trigger
955
+ and picker; remove that declaration for Shine ON. OFF preserves the halo and selected accent.
956
+ Application and OS reduced motion still take precedence; persist Shine independently from motion.
957
+ See the composition guide for the controlled picker and preference wiring.
958
+
959
+ The four separate topbar controls—gemstone, mode, design, language—stay square `2.75rem` targets
960
+ (44px at a 16px root), with localized names and tooltips. Use gemstone, sun/moon and horizontal-slider
961
+ icons, and a country flag for language. Dense gemstone options do not reduce
962
+ those launcher targets. Size icon launchers directly and keep their slotted glyphs bounded:
963
+
964
+ ```css
965
+ .appearance-launcher { --lr-icon-button-size: 2.75rem; }
966
+ .appearance-launcher::part(button) { inline-size: 2.75rem; block-size: 2.75rem; }
967
+ .appearance-launcher > svg,
968
+ .appearance-launcher > lr-icon { inline-size: 1.125rem; block-size: 1.125rem; }
969
+ ```
970
+
971
+ Apply `appearance-launcher` to each `lr-icon-button`, including buttons slotted through a popover.
972
+ Keep the mode action separate from the design fields. Set the locale picker's
973
+ `--lr-locale-picker-trigger-height: 2.75rem` and
974
+ use its public flag-only trigger with readable menu entries:
975
+
976
+ ```ts
977
+ import '@aceshooting/lyra-ui/components/lr-locale-picker.js';
978
+ import '@aceshooting/lyra-ui/components/media/flag/flag-peer.js';
979
+ ```
980
+
981
+ ```html
982
+ <lr-locale-picker top-layer trigger-display="flag" option-display="label"
983
+ aria-label="Localized language action"></lr-locale-picker>
984
+ ```
985
+
986
+ Install the optional `@aceshooting/lyra-flags` peer; the granular resolver import loads requested
987
+ flags without a bulk flag import. Leave `withoutFlags` false. Assign `locales` as a property with
988
+ `{ tag, label, country? }` entries: provide readable localized language names and an explicit ISO
989
+ country for regional entries when known, such as `en-US` → `US`. Keep flags as supplementary cues,
990
+ never the only accessible names, and preserve a valid saved locale in the controlled `value`.
991
+ Use the component's flag resolver rather than emoji, invented flag SVGs, or guessed display APIs.
992
+ Verify 320px and desktop, light/dark, RTL, enlarged text, keyboard focus, and saved preferences.
993
+
994
+ #### Two-column design panel
995
+
996
+ Compose a settings form inside `lr-popover`; use its dialog behavior rather than assigning menu or
997
+ ARIA grid roles to form fields. Import the existing native utility stylesheet and granular controls:
998
+
999
+ ```css
1000
+ @import "@aceshooting/lyra-ui/utilities.css";
1001
+
1002
+ .design-popover { --lr-overlay-max-inline-size: min(29rem, calc(100dvw - 1rem)); }
1003
+ .design-popover::part(content) { padding: 0; }
1004
+ .design-panel {
1005
+ box-sizing: border-box;
1006
+ inline-size: 29rem;
1007
+ max-inline-size: calc(100dvw - 1rem);
1008
+ padding: var(--lr-space-l);
1009
+ max-block-size: min(75dvh, 40rem);
1010
+ overflow: auto;
1011
+ overflow-wrap: anywhere;
1012
+ }
1013
+ .design-fields { --lr-grid-min-inline-size: 12rem; }
1014
+ .design-fields > * { min-inline-size: 0; max-inline-size: 100%; }
1015
+ .design-reset { inline-size: 100%; margin-block-start: var(--lr-space-l); }
1016
+ ```
1017
+
1018
+ ```ts
1019
+ import '@aceshooting/lyra-ui/components/lr-popover.js';
1020
+ import '@aceshooting/lyra-ui/components/lr-icon-button.js';
1021
+ import '@aceshooting/lyra-ui/components/lr-select.js';
1022
+ import '@aceshooting/lyra-ui/components/lr-option.js';
1023
+ import '@aceshooting/lyra-ui/components/lr-button.js';
1024
+ ```
1025
+
1026
+ ```html
1027
+ <lr-popover class="design-popover" top-layer placement="bottom-end" aria-label="Design settings">
1028
+ <lr-icon-button slot="trigger" class="appearance-launcher" label="Design settings">
1029
+ <!-- Application's decorative horizontal-slider glyph -->
1030
+ </lr-icon-button>
1031
+ <section class="design-panel">
1032
+ <div class="design-fields lr-grid-auto lr-gap-s">
1033
+ <lr-select label="Look" value="shadcn">
1034
+ <lr-option value="shadcn">Shadcn</lr-option>
1035
+ <lr-option value="lyra">Lyra</lr-option>
1036
+ <lr-option value="material">Material</lr-option>
1037
+ </lr-select>
1038
+ <lr-select label="Surface" value="glass">
1039
+ <lr-option value="glass">Glass</lr-option>
1040
+ <lr-option value="solid">Solid</lr-option>
1041
+ </lr-select>
1042
+ <lr-select label="Density" value="comfortable">
1043
+ <lr-option value="compact">Compact</lr-option>
1044
+ <lr-option value="comfortable">Comfortable</lr-option>
1045
+ <lr-option value="touch">Touch</lr-option>
1046
+ </lr-select>
1047
+ <!-- Further independent settings in their reading order -->
1048
+ </div>
1049
+ <lr-button class="design-reset" type="button">Reset appearance</lr-button>
1050
+ </section>
1051
+ </lr-popover>
1052
+ ```
1053
+
1054
+ Localize the example's labels and options, bind values to the current application state, and handle
1055
+ each select's `lr-change` through the relevant public style or preference API. Reset restores the
1056
+ application profile and any separate application preferences.
1057
+
1058
+ `lr-grid-auto` already uses `auto-fit` with a `min(100%, minimum)` track floor. A bounded `29rem`
1059
+ panel and `12rem` minimum give two columns when both fit, then one in narrow allocations; a third
1060
+ column would need at least `36rem` before gaps. Keep those bounds together when customizing the
1061
+ recipe. The existing `lr-gap-s` supplies the gap; no extra grid component or layout controller is
1062
+ needed. The minimum is measured in rem, so enlarged text can also reduce the column count.
1063
+
1064
+ Keep every field in one row-major source list. Default grid placement and native Tab order then
1065
+ agree: first row, second row, and so on; inherited RTL starts each row on the right. Do not split
1066
+ fields into separate column wrappers, reorder with CSS, or add positive tabindex values. Leave the
1067
+ full-width Reset action outside the field grid. Verify two columns at desktop allocation, one at
1068
+ 320px and enlarged text, long translated labels, RTL reading order, and Escape/focus return to the
1069
+ design launcher. Keep these layout rules shared across application headers and administrative views.
1070
+
884
1071
  ### Reading the resolved tokens from your own components — `tokens-root.css`
885
1072
 
886
1073
  The paragraph above is a real problem for any application that has custom elements of its own: they
@@ -1436,7 +1623,7 @@ resetLyraStyle(["look"]); // reset only the look axis
1436
1623
  setLyraStyle({ mode: "unset", accent: null, accentBackground: null, overrides: null });
1437
1624
  ~~~
1438
1625
 
1439
- setLyraStyle() accepts independent choices for look, surface, density, mode, accent, accentBackground, and overrides. Omitted axes keep their current selection; null resets an axis. The returned LyraStyle snapshot includes the selected values, a resolved mode when the choice is system, and lookForm to distinguish a stylesheet look from a runtime look.
1626
+ setLyraStyle() accepts independent choices for look, surface, density, mode, accent, accentBackground, and overrides. Omitted axes keep their current selection. Null restores the built-in value for look, surface, density and mode; `accent: null` explicitly clears the accent, and null clears accentBackground or overrides. `resetLyraStyle()` restores Shadcn/Glass/Emerald/System/comfortable; a field list resets only those fields. The returned LyraStyle snapshot includes the selected values, a resolved mode when the choice is system, and lookForm to distinguish a stylesheet look from a runtime look.
1440
1627
 
1441
1628
  mode is light, dark, system, or unset. Explicit modes set both data-lr-theme and data-theme; system follows the operating system and updates both attributes when it changes; unset removes Lyra's mode attributes. The lr-style-change event carries { style, changed }, where changed lists the affected fields. Applications can listen to this one event for document style changes.
1442
1629
 
@@ -1825,6 +2012,45 @@ and opacity tokens first. These additional hooks customize only the light-DOM bu
1825
2012
  | `--lr-native-table-cell-padding` | `--lr-space-s`; caption and table-cell padding |
1826
2013
  | `--lr-native-rule-space` | `--lr-space-l`; horizontal-rule block margin |
1827
2014
 
2015
+ ### Native navigation and floating chrome
2016
+
2017
+ The opt-in `.lr-surface-chrome` class uses the same protected Glass material as Lyra navigation,
2018
+ menus and modal panels. It is shipped by `theme.css` for the built-in profile and by the separate
2019
+ `surfaces/glass.css` asset for applications composing their own stylesheet set:
2020
+
2021
+ ```css
2022
+ @import "@aceshooting/lyra-ui/theme.css";
2023
+ @import "@aceshooting/lyra-ui/tokens-root.css";
2024
+ ```
2025
+
2026
+ ```html
2027
+ <nav class="lr-surface-chrome" aria-label="Primary navigation">…</nav>
2028
+ <section class="lr-surface-chrome" aria-labelledby="settings-title">
2029
+ <h2 id="settings-title">Settings</h2>
2030
+ <div class="settings-scrollport">…</div>
2031
+ </section>
2032
+ ```
2033
+
2034
+ Localize the example's names. Keep the material wrapper non-scrolling and put overflow on an inner
2035
+ scrollport. The decorative pseudo-element filters the backdrop without changing fixed descendant
2036
+ coordinates. The wrapper reserves `::before` and supplies a low-specificity `position: relative`;
2037
+ application fixed, sticky or absolute positioning still wins. Avoid an extra opaque wrapper inside
2038
+ an already treated Lyra popup.
2039
+
2040
+ `--lr-surface-background` optionally supplies this native wrapper's base fill. It falls back to the
2041
+ local high container surface, then the overlay surface, and resolves on the painted wrapper, so nearer
2042
+ theme inputs work.
2043
+ The existing `--lr-theme-surface-opacity`, `--lr-theme-surface-blur`,
2044
+ `--lr-theme-surface-saturation` and `--lr-theme-surface-highlight` controls apply. Glass uses 70%
2045
+ opacity by default, 12px blur with a 16px ceiling, and qualified text, edges and focus.
2046
+ The public opacity input accepts 0–1; lower custom opacity may expose backdrops that need
2047
+ stronger foreground contrast. Solid and accessibility preferences still force opaque fills.
2048
+ Explicit `data-lr-surface="solid"`, unsupported backdrop filtering, reduced transparency, increased
2049
+ contrast and forced colors retain opaque fills. Load `preferences.css` for explicit inherited
2050
+ contrast/motion choices. Nested chrome suppresses repeated blur; independently presented top-layer
2051
+ surfaces begin their own material root. Keep cards, data tables, charts, map layers and editing
2052
+ fields outside the automatic chrome class.
2053
+
1828
2054
  ## Localization: `locale`, `strings`, and the locale runtime
1829
2055
 
1830
2056
  Every built-in string — button labels, accessible names, descriptions, validation messages, status
@@ -2755,7 +2981,10 @@ void`, and `virtualAnchorFromRect()`** — thin wrapper over `@floating-ui/dom`'
2755
2981
  `computePosition` + `autoUpdate`. Forces `strategy: 'fixed'` (matching the
2756
2982
  popup's own `position: fixed` CSS — otherwise it lands offset by the page scroll), middleware
2757
2983
  `offset(opts.offset ?? 4)`, `flip()`, `shift({ padding: 8 })`, default `placement: 'bottom-start'`.
2758
- Returns a cleanup function that stops the `autoUpdate` loop — call it in `disconnectedCallback()`.
2984
+ Returns a cleanup function that stops observation and queued updates — call it in `disconnectedCallback()`.
2985
+ For `place()`, element-resize notifications coalesce into the next animation frame; initial
2986
+ computation, scrolling and layout-shift updates begin immediately. Cleanup cancels a pending
2987
+ resize frame.
2759
2988
  `trackRect()` reports the target's initial viewport rect exactly once before returning, follows
2760
2989
  later layout/viewport changes, and returns the same cleanup shape.
2761
2990
  `virtualAnchorFromRect()` adapts a live rectangle provider to the exported `VirtualAnchor`
@@ -5303,10 +5532,8 @@ These named interfaces and helper signatures are available to typed integrations
5303
5532
 
5304
5533
  ### Composing looks, surfaces and density
5305
5534
 
5306
- The independent style API is exported from `@aceshooting/lyra-ui/theme.js`.
5307
- A scope selects one look, one surface, one density, one mode and one accent. These choices compose:
5308
- shadcn with glass and compact density is valid. Selecting another look replaces that scope's look;
5309
- it does not stack two competing look definitions.
5535
+ `@aceshooting/lyra-ui/theme.js` exports the API. Each scope selects one look, surface, density,
5536
+ mode and accent; the axes compose independently.
5310
5537
 
5311
5538
  ```js
5312
5539
  import '@aceshooting/lyra-ui/theme.css';
@@ -5318,60 +5545,48 @@ import '@aceshooting/lyra-ui/accents.css';
5318
5545
  import { setLyraStyle, resetLyraStyle, applyLyraStyleScope } from '@aceshooting/lyra-ui/theme.js';
5319
5546
 
5320
5547
  setLyraStyle({ look: 'shadcn', mode: 'system', accent: 'sapphire' });
5321
- setLyraStyle({ surface: 'glass' }); // keeps the other choices
5322
- applyLyraStyleScope(tableRegion, { density: 'compact' }); // other axes inherit
5548
+ setLyraStyle({ surface: 'glass' }); // keeps others
5549
+ applyLyraStyleScope(tableRegion, { density: 'compact' }); // others inherit
5323
5550
  applyLyraStyleScope(previewRegion, { look: 'material', mode: 'dark' });
5324
- resetLyraStyle(['look']); // restores the Lyra look, retaining the other fields
5325
- applyLyraStyleScope(tableRegion, null); // restores the element's previous authored values
5551
+ resetLyraStyle(['look']); // resets look only
5552
+ applyLyraStyleScope(tableRegion, null); // restores authored values
5326
5553
  ```
5327
5554
 
5328
- `setLyraStyle()` merges omitted fields and persists the whole-page selection. `null` resets a field.
5329
- `applyLyraStyleScope()` replaces the element's complete selection: omitted fields inherit. It neither
5330
- persists nor dispatches global events. Author changes made after the helper's last write are preserved
5331
- when the scope is cleared. `getLyraStyle()` reports requested axes and the resolved mode.
5332
-
5333
- Each attribute can also be authored directly: `data-lr-look`, `data-lr-surface`, `data-lr-density`,
5334
- `data-lr-mode` and `data-lr-accent`. A stylesheet look id requires its stylesheet; setting an arbitrary
5335
- id does not load or register a look. Use `defineLyraLook({ id, tokens })` for a validated, immutable
5336
- runtime definition, then pass it as `look`. `lyraLookCss()` from `theme/look-css.js` produces the
5337
- stylesheet form without accessing the DOM. Install `theme.css` and the selected optional sheets in
5338
- an application-owned shadow root that contains its own style boundaries; document selectors do not
5339
- cross shadow roots. Inherited values do cross them.
5340
-
5341
- For design-tool interchange, `@aceshooting/lyra-ui/design-tokens.json` includes
5342
- `$extensions['com.aceshooting.lyra.looks']` with `schemaVersion: 1`, `base: 'lyra'`, and a
5343
- `definitions` map for the shipped looks, including `lyra`, `material`, `shadcn`, `data`, `terminal`
5344
- and `high-contrast`. Each entry is a portable `{ id, tokens }`
5345
- definition accepted by `defineLyraLook()`. Sparse and null branches remain sparse; omitted values
5346
- come from the canonical base token tree, and the empty Lyra definition restores that base. Load the
5347
- artifact explicitly only in tooling or flows that need it; ordinary components do not import it.
5348
-
5349
- ### Documentation theme builder
5350
-
5351
- The optional [theme builder](https://www.lyra-ui.com/docs/?path=/story/theming-theme-builder--editor)
5352
- composes existing style APIs and portable token maps. It previews both modes, supports individual
5353
- and complete resets, and edits contrast/motion preferences, local-font pairing, shape, elevation
5354
- and categorical/sequential/diverging palettes. The editor is documentation code, not a package
5355
- entry point or a new custom element; importing components never imports the builder.
5356
-
5357
- Import/export uses the existing `LyraLook`, `LyraThemeTokens`, version-2 saved style record and
5358
- `LyraPreferences` formats. Preferences remain separate from the saved style record. Runtime look
5359
- tokens are retained explicitly; `getLyraStyle()` snapshots alone do not contain those tokens.
5360
- Imports validate atomically, are bounded to 256 KiB, and reject network-bearing or executable CSS.
5361
- Errors leave the last valid preview intact. A group reset removes that group's writes; resetting
5362
- one token to its look value removes it from every override group.
5363
-
5364
- Exported look CSS comes from `lyraLookCss()` and requires `theme.css`, the selected optional sheets
5365
- and axis attributes. It is not an export of every axis or preference. Use the complete runtime
5366
- recipe for custom accent derivation, or the separate style/preference files to retain those choices.
5367
- Server-rendered attributes use `lyraStyleAttributes()` and `lyraPreferenceAttributes()`; system mode
5368
- is not falsely resolved on the server. Install the required CSS in each application-owned shadow
5369
- root that contains a local style boundary.
5370
-
5371
- Diagnostics describe measured specimen colors and states, not universal accessibility
5372
- certification. Unknown/dynamic backgrounds remain unmeasured. Chart series keep text and non-color
5373
- cues; color-vision simulation does not replace them. Font availability, physical blur and native
5374
- platform accessibility settings still require evidence on the relevant platform.
5555
+ `setLyraStyle()` persists supplied fields and retains omitted ones; null resets profile axes, while
5556
+ `accent: null` clears it. `applyLyraStyleScope()` replaces an element's selection (omitted fields
5557
+ inherit), without persistence or global events; clearing preserves later author changes. `getLyraStyle()`
5558
+ reports requested axes and resolved mode.
5559
+
5560
+ Set `data-lr-look`, `data-lr-surface`, `data-lr-density`, `data-lr-mode` and `data-lr-accent`
5561
+ directly if needed. Stylesheet look ids need their sheet; arbitrary ids neither load nor register.
5562
+ `defineLyraLook({ id, tokens })` defines a validated immutable runtime look;
5563
+ `lyraLookCss()` from `theme/look-css.js` creates CSS without DOM access. In app-owned shadow roots
5564
+ with local boundaries, install `theme.css` and selected sheets; selectors stop at roots, inheritance
5565
+ crosses.
5566
+
5567
+ `@aceshooting/lyra-ui/design-tokens.json` exports `$extensions['com.aceshooting.lyra.looks']`
5568
+ (schemaVersion 1, base `lyra`), definitions `lyra`, `material`, `shadcn`, `data`, `terminal`,
5569
+ `high-contrast`, and `defaultStyle`: Shadcn/Glass/Emerald/System/comfortable. The original token tree remains
5570
+ authoritative; empty `lyra` restores it. Runtime CSS/editor/preview project the default separately.
5571
+ Portable `{ id, tokens }` works with `defineLyraLook()`; sparse/null branches stay sparse. Load its
5572
+ resolver to apply a look.
5573
+
5574
+ The [theme builder](https://www.lyra-ui.com/docs/?path=/story/theming-theme-builder--editor) previews
5575
+ modes and edits contrast/motion, fonts, shape, elevation and chart palettes. It is documentation only,
5576
+ not an entry point or element; component imports do not load it.
5577
+
5578
+ Import/export uses `LyraLook`, `LyraThemeTokens`, version-2 saved-style records and separate
5579
+ `LyraPreferences`. Preserve runtime look tokens; `getLyraStyle()` snapshots omit them. Imports are
5580
+ atomic (256 KiB max), reject network-bearing/executable CSS and preserve the last preview on error.
5581
+ Group reset removes its writes; resetting a token to its look value removes it from every group.
5582
+
5583
+ `lyraLookCss()` exports only look CSS (requires `theme.css`, selected sheets and axis attributes).
5584
+ Use the runtime recipe for custom accent derivation or separate style/preference files. SSR helpers
5585
+ `lyraStyleAttributes()` and `lyraPreferenceAttributes()` leave system mode unresolved. Install CSS
5586
+ in every app-owned shadow root with a local boundary.
5587
+
5588
+ Diagnostics measure specimens, not certify accessibility; dynamic backgrounds are unmeasured. Keep
5589
+ chart text/non-color cues. See [contrast guidance](#scoped-contrast-and-motion-preferences).
5375
5590
 
5376
5591
  ### Optional shape, typography and elevation presets
5377
5592
 
@@ -5538,18 +5753,42 @@ lyraStyleAttributes() provide DOM-free server-rendering helpers; render the retu
5538
5753
  through the framework's normal HTML escaping.
5539
5754
 
5540
5755
  Glass is a treatment for eligible navigation and floating chrome. It does not make content panels,
5541
- forms, charts or dialogs translucent. Unsupported blur, reduced transparency, increased contrast and
5756
+ editing controls, charts or base map layers translucent. Dialog and drawer panels, menus and
5757
+ control-owned listboxes share the chrome treatment; their input interiors stay opaque. Unsupported blur, reduced transparency, increased contrast and
5542
5758
  forced colors retain solid fills. Solid surfaces use `backdrop-filter: none`; forced colours paint
5543
5759
  `Canvas`. Offer a solid choice wherever the application offers glass, since reduced-transparency
5544
5760
  media-query support varies between browsers.
5545
5761
 
5546
- Regular glass defaults to 90% opacity, with a 90% minimum and a 12px blur clamped to 16px.
5762
+ Regular glass defaults to 70% opacity with a 12px blur clamped to 16px.
5763
+ The public `--lr-theme-surface-opacity` input accepts 0 through 1. Lower opacity exposes more
5764
+ of the backdrop; the default foreground qualification covers 70%, while a custom lower setting
5765
+ cannot guarantee contrast against every backdrop. Solid and accessibility preferences retain
5766
+ opaque fills regardless of this input.
5547
5767
  Quiet text, necessary control edges, focus indicators and transparent actions gain a local
5548
5768
  contrast-qualified foreground; opaque accent fills retain their own on-colours. Supported chrome
5549
5769
  includes app rails, navigation menus, menubars, menus and their context-menu composition, popovers,
5550
5770
  selection toolbars, toast items and the owned playback-rate toolbar of `lr-av-player`. Nested glass
5551
- chrome is opaque, preventing repeated blur. Content cards and modal dialogs remain solid.
5552
- Scrolling rail, popover and selection-toolbar surfaces keep a stationary decorative blur layer;
5771
+ chrome is opaque, preventing repeated blur. Independently promoted menus and modal panels start a
5772
+ new material root. Content cards and editing fields remain opaque.
5773
+ A design panel can offer a Glass opacity range from 0–100%, shown when the selected surface is
5774
+ Glass. Start and reset it at 70%; convert the displayed percentage to the public token's 0–1 range.
5775
+ Apply this CSS input independently of look overrides: `setLyraStyle()` does not accept surface
5776
+ inputs in its `overrides` allowlist. Persist the percentage in the application's own settings and
5777
+ apply it before first paint, including after restoring those settings. Reset the app setting to 70
5778
+ and reapply it. Native `.lr-surface-chrome` wrappers and eligible component chrome consume the
5779
+ same input:
5780
+
5781
+ ```js
5782
+ function applyGlassOpacity(percent) {
5783
+ if (!Number.isFinite(percent)) return;
5784
+ const opacity = Math.min(100, Math.max(0, percent)) / 100;
5785
+ document.documentElement.style.setProperty('--lr-theme-surface-opacity', String(opacity));
5786
+ }
5787
+
5788
+ applyGlassOpacity(70); // Default and reset value; apply saved app settings before first paint.
5789
+ ```
5790
+
5791
+ Scrolling rail, popup, modal-panel and selection-toolbar surfaces keep a stationary decorative blur layer;
5553
5792
  the public surface continues to own scrolling, focus and author overflow hooks.
5554
5793
 
5555
5794
  `lr-av-player` additionally offers `controls-surface="clear"`, restricted to its owned toolbar and