@fieldia/widgets 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/package.json +2 -2
  2. package/src/index.d.mts +2 -0
  3. package/src/index.d.ts +2 -0
  4. package/src/index.js +6 -1
  5. package/src/index.js.map +1 -1
  6. package/src/index.mjs +2 -0
  7. package/src/index.mjs.map +1 -1
  8. package/src/lib/badge.d.mts +8 -0
  9. package/src/lib/badge.d.ts +8 -0
  10. package/src/lib/badge.js +37 -0
  11. package/src/lib/badge.js.map +1 -0
  12. package/src/lib/badge.mjs +33 -0
  13. package/src/lib/badge.mjs.map +1 -0
  14. package/src/lib/calendar.d.mts +3 -1
  15. package/src/lib/calendar.d.ts +3 -1
  16. package/src/lib/calendar.js +17 -1
  17. package/src/lib/calendar.js.map +1 -1
  18. package/src/lib/calendar.mjs +17 -1
  19. package/src/lib/calendar.mjs.map +1 -1
  20. package/src/lib/cards.js +12 -4
  21. package/src/lib/cards.js.map +1 -1
  22. package/src/lib/cards.mjs +13 -5
  23. package/src/lib/cards.mjs.map +1 -1
  24. package/src/lib/choice-images.js +1 -1
  25. package/src/lib/choice-images.js.map +1 -1
  26. package/src/lib/choice-images.mjs +1 -1
  27. package/src/lib/choice-images.mjs.map +1 -1
  28. package/src/lib/choice-tags.js +6 -4
  29. package/src/lib/choice-tags.js.map +1 -1
  30. package/src/lib/choice-tags.mjs +6 -4
  31. package/src/lib/choice-tags.mjs.map +1 -1
  32. package/src/lib/colour.d.mts +11 -0
  33. package/src/lib/colour.d.ts +11 -0
  34. package/src/lib/colour.js +114 -0
  35. package/src/lib/colour.js.map +1 -0
  36. package/src/lib/colour.mjs +110 -0
  37. package/src/lib/colour.mjs.map +1 -0
  38. package/src/lib/copy.d.mts +8 -0
  39. package/src/lib/copy.d.ts +8 -0
  40. package/src/lib/copy.js +58 -0
  41. package/src/lib/copy.js.map +1 -0
  42. package/src/lib/copy.mjs +54 -0
  43. package/src/lib/copy.mjs.map +1 -0
  44. package/src/lib/date-range.d.mts +2 -0
  45. package/src/lib/date-range.d.ts +2 -0
  46. package/src/lib/date-range.js +220 -0
  47. package/src/lib/date-range.js.map +1 -0
  48. package/src/lib/date-range.mjs +216 -0
  49. package/src/lib/date-range.mjs.map +1 -0
  50. package/src/lib/display.d.mts +25 -1
  51. package/src/lib/display.d.ts +25 -1
  52. package/src/lib/display.js +42 -2
  53. package/src/lib/display.js.map +1 -1
  54. package/src/lib/display.mjs +39 -2
  55. package/src/lib/display.mjs.map +1 -1
  56. package/src/lib/distribution.d.mts +13 -0
  57. package/src/lib/distribution.d.ts +13 -0
  58. package/src/lib/distribution.js +159 -0
  59. package/src/lib/distribution.js.map +1 -0
  60. package/src/lib/distribution.mjs +152 -0
  61. package/src/lib/distribution.mjs.map +1 -0
  62. package/src/lib/duration.d.mts +18 -0
  63. package/src/lib/duration.d.ts +18 -0
  64. package/src/lib/duration.js +137 -0
  65. package/src/lib/duration.js.map +1 -0
  66. package/src/lib/duration.mjs +128 -0
  67. package/src/lib/duration.mjs.map +1 -0
  68. package/src/lib/embed.d.mts +3 -0
  69. package/src/lib/embed.d.ts +3 -0
  70. package/src/lib/embed.js +97 -0
  71. package/src/lib/embed.js.map +1 -0
  72. package/src/lib/embed.mjs +92 -0
  73. package/src/lib/embed.mjs.map +1 -0
  74. package/src/lib/extras.js +6 -0
  75. package/src/lib/extras.js.map +1 -1
  76. package/src/lib/extras.mjs +6 -0
  77. package/src/lib/extras.mjs.map +1 -1
  78. package/src/lib/files.d.mts +11 -0
  79. package/src/lib/files.d.ts +11 -0
  80. package/src/lib/files.js +19 -0
  81. package/src/lib/files.js.map +1 -1
  82. package/src/lib/files.mjs +18 -0
  83. package/src/lib/files.mjs.map +1 -1
  84. package/src/lib/float.d.mts +14 -0
  85. package/src/lib/float.d.ts +14 -0
  86. package/src/lib/float.js +91 -0
  87. package/src/lib/float.js.map +1 -0
  88. package/src/lib/float.mjs +88 -0
  89. package/src/lib/float.mjs.map +1 -0
  90. package/src/lib/kind-parts.d.mts +4 -3
  91. package/src/lib/kind-parts.d.ts +4 -3
  92. package/src/lib/kind-parts.js +5 -3
  93. package/src/lib/kind-parts.js.map +1 -1
  94. package/src/lib/kind-parts.mjs +5 -3
  95. package/src/lib/kind-parts.mjs.map +1 -1
  96. package/src/lib/labels.d.mts +39 -0
  97. package/src/lib/labels.d.ts +39 -0
  98. package/src/lib/labels.js +29 -0
  99. package/src/lib/labels.js.map +1 -1
  100. package/src/lib/labels.mjs +29 -0
  101. package/src/lib/labels.mjs.map +1 -1
  102. package/src/lib/layout-styles.d.mts +1 -1
  103. package/src/lib/layout-styles.d.ts +1 -1
  104. package/src/lib/layout-styles.js +12 -5
  105. package/src/lib/layout-styles.js.map +1 -1
  106. package/src/lib/layout-styles.mjs +12 -5
  107. package/src/lib/layout-styles.mjs.map +1 -1
  108. package/src/lib/lines.d.mts +12 -2
  109. package/src/lib/lines.d.ts +12 -2
  110. package/src/lib/lines.js +372 -25
  111. package/src/lib/lines.js.map +1 -1
  112. package/src/lib/lines.mjs +371 -26
  113. package/src/lib/lines.mjs.map +1 -1
  114. package/src/lib/links-table.d.mts +11 -0
  115. package/src/lib/links-table.d.ts +11 -0
  116. package/src/lib/links-table.js +116 -0
  117. package/src/lib/links-table.js.map +1 -0
  118. package/src/lib/links-table.mjs +112 -0
  119. package/src/lib/links-table.mjs.map +1 -0
  120. package/src/lib/locales/ar.js +29 -0
  121. package/src/lib/locales/ar.js.map +1 -1
  122. package/src/lib/locales/ar.mjs +29 -0
  123. package/src/lib/locales/ar.mjs.map +1 -1
  124. package/src/lib/locales/de.js +29 -0
  125. package/src/lib/locales/de.js.map +1 -1
  126. package/src/lib/locales/de.mjs +29 -0
  127. package/src/lib/locales/de.mjs.map +1 -1
  128. package/src/lib/locales/fr.js +29 -0
  129. package/src/lib/locales/fr.js.map +1 -1
  130. package/src/lib/locales/fr.mjs +29 -0
  131. package/src/lib/locales/fr.mjs.map +1 -1
  132. package/src/lib/numbers.d.mts +5 -1
  133. package/src/lib/numbers.d.ts +5 -1
  134. package/src/lib/numbers.js +15 -2
  135. package/src/lib/numbers.js.map +1 -1
  136. package/src/lib/numbers.mjs +13 -2
  137. package/src/lib/numbers.mjs.map +1 -1
  138. package/src/lib/payments.d.mts +2 -0
  139. package/src/lib/payments.d.ts +2 -0
  140. package/src/lib/payments.js +94 -0
  141. package/src/lib/payments.js.map +1 -0
  142. package/src/lib/payments.mjs +90 -0
  143. package/src/lib/payments.mjs.map +1 -0
  144. package/src/lib/popup.d.mts +11 -0
  145. package/src/lib/popup.d.ts +11 -0
  146. package/src/lib/popup.js +48 -0
  147. package/src/lib/popup.js.map +1 -0
  148. package/src/lib/popup.mjs +45 -0
  149. package/src/lib/popup.mjs.map +1 -0
  150. package/src/lib/priority.d.mts +10 -0
  151. package/src/lib/priority.d.ts +10 -0
  152. package/src/lib/priority.js +59 -0
  153. package/src/lib/priority.js.map +1 -0
  154. package/src/lib/priority.mjs +55 -0
  155. package/src/lib/priority.mjs.map +1 -0
  156. package/src/lib/progress.js +3 -0
  157. package/src/lib/progress.js.map +1 -1
  158. package/src/lib/progress.mjs +3 -0
  159. package/src/lib/progress.mjs.map +1 -1
  160. package/src/lib/properties.js +100 -9
  161. package/src/lib/properties.js.map +1 -1
  162. package/src/lib/properties.mjs +100 -9
  163. package/src/lib/properties.mjs.map +1 -1
  164. package/src/lib/read-text.d.mts +25 -0
  165. package/src/lib/read-text.d.ts +25 -0
  166. package/src/lib/read-text.js +102 -0
  167. package/src/lib/read-text.js.map +1 -0
  168. package/src/lib/read-text.mjs +98 -0
  169. package/src/lib/read-text.mjs.map +1 -0
  170. package/src/lib/relations.d.mts +12 -0
  171. package/src/lib/relations.d.ts +12 -0
  172. package/src/lib/relations.js +110 -10
  173. package/src/lib/relations.js.map +1 -1
  174. package/src/lib/relations.mjs +108 -10
  175. package/src/lib/relations.mjs.map +1 -1
  176. package/src/lib/slider.js +1 -1
  177. package/src/lib/slider.js.map +1 -1
  178. package/src/lib/slider.mjs +1 -1
  179. package/src/lib/slider.mjs.map +1 -1
  180. package/src/lib/state-dot.d.mts +2 -0
  181. package/src/lib/state-dot.d.ts +2 -0
  182. package/src/lib/state-dot.js +107 -0
  183. package/src/lib/state-dot.js.map +1 -0
  184. package/src/lib/state-dot.mjs +103 -0
  185. package/src/lib/state-dot.mjs.map +1 -0
  186. package/src/lib/statusbar.js +151 -14
  187. package/src/lib/statusbar.js.map +1 -1
  188. package/src/lib/statusbar.mjs +151 -14
  189. package/src/lib/statusbar.mjs.map +1 -1
  190. package/src/lib/styles-business.d.mts +8 -0
  191. package/src/lib/styles-business.d.ts +8 -0
  192. package/src/lib/styles-business.js +120 -0
  193. package/src/lib/styles-business.js.map +1 -0
  194. package/src/lib/styles-business.mjs +117 -0
  195. package/src/lib/styles-business.mjs.map +1 -0
  196. package/src/lib/styles-inputs.d.mts +1 -1
  197. package/src/lib/styles-inputs.d.ts +1 -1
  198. package/src/lib/styles-inputs.js +2 -0
  199. package/src/lib/styles-inputs.js.map +1 -1
  200. package/src/lib/styles-inputs.mjs +2 -0
  201. package/src/lib/styles-inputs.mjs.map +1 -1
  202. package/src/lib/styles-kinds.d.mts +1 -1
  203. package/src/lib/styles-kinds.d.ts +1 -1
  204. package/src/lib/styles-kinds.js +2 -2
  205. package/src/lib/styles-kinds.mjs +2 -2
  206. package/src/lib/styles-sheet.d.mts +6 -0
  207. package/src/lib/styles-sheet.d.ts +6 -0
  208. package/src/lib/styles-sheet.js +139 -0
  209. package/src/lib/styles-sheet.js.map +1 -0
  210. package/src/lib/styles-sheet.mjs +136 -0
  211. package/src/lib/styles-sheet.mjs.map +1 -0
  212. package/src/lib/styles.js +223 -27
  213. package/src/lib/styles.js.map +1 -1
  214. package/src/lib/styles.mjs +223 -27
  215. package/src/lib/styles.mjs.map +1 -1
  216. package/src/lib/tax-totals.d.mts +2 -0
  217. package/src/lib/tax-totals.d.ts +2 -0
  218. package/src/lib/tax-totals.js +92 -0
  219. package/src/lib/tax-totals.js.map +1 -0
  220. package/src/lib/tax-totals.mjs +88 -0
  221. package/src/lib/tax-totals.mjs.map +1 -0
  222. package/src/lib/themes.d.mts +29 -0
  223. package/src/lib/themes.d.ts +29 -0
  224. package/src/lib/themes.js +180 -0
  225. package/src/lib/themes.js.map +1 -0
  226. package/src/lib/themes.mjs +177 -0
  227. package/src/lib/themes.mjs.map +1 -0
  228. package/src/lib/timer.d.mts +4 -0
  229. package/src/lib/timer.d.ts +4 -0
  230. package/src/lib/timer.js +62 -0
  231. package/src/lib/timer.js.map +1 -0
  232. package/src/lib/timer.mjs +57 -0
  233. package/src/lib/timer.mjs.map +1 -0
  234. package/src/lib/widgets.d.mts +18 -3
  235. package/src/lib/widgets.d.ts +18 -3
  236. package/src/lib/widgets.js +89 -10
  237. package/src/lib/widgets.js.map +1 -1
  238. package/src/lib/widgets.mjs +90 -11
  239. package/src/lib/widgets.mjs.map +1 -1
  240. package/src/lib/yes-no.js +1 -1
  241. package/src/lib/yes-no.js.map +1 -1
  242. package/src/lib/yes-no.mjs +1 -1
  243. package/src/lib/yes-no.mjs.map +1 -1
package/src/lib/styles.js CHANGED
@@ -6,6 +6,8 @@ const styles_kinds_1 = require("./styles-kinds");
6
6
  const styles_choices_1 = require("./styles-choices");
7
7
  const styles_inputs_1 = require("./styles-inputs");
8
8
  const styles_parts_1 = require("./styles-parts");
9
+ const styles_sheet_1 = require("./styles-sheet");
10
+ const styles_business_1 = require("./styles-business");
9
11
  /**
10
12
  * Fieldia's stylesheet: two skins and the layout chrome, all scoped to the
11
13
  * form's own root (`.fd-form[data-fd-skin=…]`), so two forms on one page can
@@ -20,6 +22,7 @@ const styles_parts_1 = require("./styles-parts");
20
22
  * form mirrors without a second stylesheet.
21
23
  */
22
24
  const layout_styles_1 = require("./layout-styles");
25
+ const themes_1 = require("./themes");
23
26
  /**
24
27
  * The widths of a form at which its groups take their medium and their narrow
25
28
  * columns: up to 760px and up to 520px of the form's own width, as the
@@ -29,8 +32,11 @@ const layout_styles_1 = require("./layout-styles");
29
32
  exports.FORM_WIDTHS = { medium: 760, narrow: 520 };
30
33
  /** The skins and the parts' chrome. One literal, so the script bundle can minify it as CSS. */
31
34
  const SKINS_CSS = /* css */ `
32
- /* .fd-theme carries the same tokens for things outside a form, such as a dialog over the page. One inside a form
35
+ /* Fieldia's tokens (its colours, sizes and fonts) live in a cascade layer: a host's own rule, of any weight, sets
36
+ them over Fieldia's, whole. The skins, themes, page looks and schemes keep their order inside it.
37
+ .fd-theme carries the same tokens for things outside a form, such as a dialog over the page. One inside a form
33
38
  with no skin of its own (the conversation beside a record) wears the form's skin and scheme instead. */
39
+ @layer fieldia-tokens {
34
40
  .fd-form, .fd-theme:is([data-fd-skin], :not(.fd-form *)) {
35
41
  --fd-font: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", "Noto Sans Arabic", sans-serif;
36
42
  --fd-text: #212529;
@@ -60,12 +66,6 @@ const SKINS_CSS = /* css */ `
60
66
  --fd-label-weight: 600;
61
67
  --fd-gap-x: 32px;
62
68
  --fd-gap-y: 14px;
63
- container-type: inline-size;
64
- font-family: var(--fd-font);
65
- font-size: 14px;
66
- line-height: 1.45;
67
- color: var(--fd-text);
68
- -webkit-text-size-adjust: 100%;
69
69
  }
70
70
  /* Ant Design's blue and red, a shade darker: words in them read at 4.5:1 (WCAG AA) on white, the page and their soft shades. */
71
71
  .fd-form[data-fd-skin="outlined"], .fd-theme[data-fd-skin="outlined"] {
@@ -89,6 +89,15 @@ const SKINS_CSS = /* css */ `
89
89
  --fd-gap-x: 24px;
90
90
  --fd-gap-y: 18px;
91
91
  }
92
+ }
93
+ .fd-form, .fd-theme:is([data-fd-skin], :not(.fd-form *)) {
94
+ container-type: inline-size;
95
+ font-family: var(--fd-font);
96
+ font-size: 14px;
97
+ line-height: 1.45;
98
+ color: var(--fd-text);
99
+ -webkit-text-size-adjust: 100%;
100
+ }
92
101
  .fd-form *, .fd-form *::before, .fd-form *::after { box-sizing: border-box; }
93
102
  .fd-form [hidden] { display: none !important; }
94
103
 
@@ -123,14 +132,31 @@ const SKINS_CSS = /* css */ `
123
132
  align-items: start;
124
133
  }
125
134
  .fd-grid > * { grid-column: span min(var(--fd-span, 1), var(--fd-cols)); }
135
+ /* Twelfths keep the page's gap while it takes under half their width, so they line up with the columns
136
+ round them; in a narrow column it shrinks with them instead of pushing past its edge. */
137
+ .fd-grid[data-twelfths] { column-gap: min(var(--fd-gap-x), 100% / 24); }
126
138
  .fd-field { display: grid; gap: 4px; min-width: 0; }
127
139
  .fd-label { font-weight: var(--fd-label-weight); color: var(--fd-text); }
128
140
  /* The ✓ of a field filled in right, by its label. */
129
141
  .fd-valid-mark { color: var(--fd-success); width: 1em; height: 1em; margin-inline-start: 6px; vertical-align: -0.15em; stroke-width: 2.4; }
130
- .fd-field.fd-required > .fd-label::after { content: " *"; color: var(--fd-error); }
131
- .fd-form[data-fd-skin="outlined"] .fd-field.fd-required > .fd-label::after { content: ""; }
132
- .fd-form[data-fd-skin="outlined"] .fd-field.fd-required > .fd-label::before { content: "* "; color: var(--fd-error); }
142
+ /* No space between the star and the label's last word, its gap a margin: a line never breaks before it. */
143
+ .fd-field.fd-required > .fd-label::after { content: "*"; margin-inline-start: 0.25em; color: var(--fd-error); }
144
+ .fd-form[data-fd-skin="outlined"] .fd-field.fd-required > .fd-label::after { content: none; }
145
+ .fd-form[data-fd-skin="outlined"] .fd-field.fd-required > .fd-label::before { content: "*"; margin-inline-end: 0.25em; color: var(--fd-error); }
133
146
  .fd-help { color: var(--fd-muted); font-size: 12.5px; }
147
+ /* A field's help behind a (?) by its label: a bubble on hover, focus or a tap. */
148
+ .fd-help-tip-wrap { position: relative; display: inline-flex; vertical-align: 0.05em; margin-inline-start: 6px; }
149
+ /* In a label it stands just after the last word, out of the line's flow: a browser may always break a line
150
+ before a box such as the (?), no-break space or not, and it would wrap onto a line of its own.
151
+ The label keeps room for it at its end, and a required star moves past it. */
152
+ .fd-label > .fd-help-tip-wrap { position: absolute; margin-block-start: 0.15em; }
153
+ .fd-label:has(> .fd-help-tip-wrap) { padding-inline-end: 22px; }
154
+ .fd-field.fd-required > .fd-label:has(> .fd-help-tip-wrap)::after { padding-inline-start: 22px; }
155
+ .fd-form:not([data-fd-skin="outlined"]) .fd-field.fd-required > .fd-label:has(> .fd-help-tip-wrap) { padding-inline-end: 0; }
156
+ .fd-help-tip { all: unset; box-sizing: border-box; display: inline-grid; place-items: center; width: 16px; height: 16px; border: 1px solid var(--fd-border); border-radius: 50%; color: var(--fd-muted); font-size: 11px; font-weight: 600; line-height: 1; cursor: help; }
157
+ .fd-help-tip:hover, .fd-help-tip[aria-expanded="true"] { color: var(--fd-accent); border-color: var(--fd-accent); }
158
+ .fd-help-tip:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: 2px; }
159
+ .fd-help-bubble { position: absolute; inset-block-start: calc(100% + 6px); inset-inline-start: -8px; z-index: 30; width: max-content; max-width: min(280px, calc(100vw - 16px)); padding: 6px 9px; border-radius: 6px; background: var(--fd-text); color: var(--fd-surface); font-size: 12.5px; font-weight: 400; line-height: 1.4; white-space: normal; box-shadow: 0 6px 18px rgb(0 0 0 / 0.18); }
134
160
  /*
135
161
  * A page's words run the way they are written — a sentence left in English on
136
162
  * an Arabic page keeps its full stop at its end — and line up with the form.
@@ -151,13 +177,28 @@ const SKINS_CSS = /* css */ `
151
177
  /* One label width for every field, so a field spanning two columns lines up with its neighbours. */
152
178
  grid-template-columns: var(--fd-label-width, 11em) minmax(0, 1fr);
153
179
  column-gap: 12px;
154
- align-items: baseline;
155
180
  }
156
- .fd-form[data-fd-skin="underline"] .fd-field:where(:not([data-labels])) > .fd-label { grid-column: 1; }
181
+ /* The label at its value's top, its words level with a one-line box's, as labels set beside by a page sit: never
182
+ by the value's baseline, which a box of several lines (a code box, rich text, files) puts at its foot. */
183
+ .fd-form[data-fd-skin="underline"] .fd-field:where(:not([data-labels])) > .fd-label {
184
+ grid-column: 1; align-self: start; padding-block-start: max(0px, calc((var(--fd-control-height, 30px) - 1.45em) / 2));
185
+ }
157
186
  /* A table of lines needs the full width: its label sits above it. */
158
187
  .fd-form[data-fd-skin="underline"] .fd-field[data-type="one2many"] { grid-template-columns: minmax(0, 1fr); }
159
188
  .fd-form[data-fd-skin="underline"] .fd-field[data-type="one2many"] > * { grid-column: 1 !important; }
160
189
  .fd-form[data-fd-skin="underline"] .fd-field:where(:not([data-labels])) > :not(.fd-label) { grid-column: 2; }
190
+ /* A row of twelfths led by a field with its label beside — the skin's (data-row="skin") or the page's
191
+ ("beside") — Flectra's o_row: that label sits with the labels round it, the parts share the values' room. */
192
+ .fd-form[data-fd-skin="underline"] .fd-section[data-row="skin"] { --fd-row-label: var(--fd-label-width, 11em); --fd-row-gap: 12px; --fd-row-place: absolute; --fd-row-drop: max(0px, calc((var(--fd-control-height, 30px) - 1.45em) / 2)); }
193
+ .fd-form .fd-section[data-row="beside"] { --fd-row-label: var(--fd-label-width, 140px); --fd-row-gap: 14px; --fd-row-place: absolute; --fd-row-drop: max(0px, calc((var(--fd-control-height, 30px) - 1.45em) / 2)); }
194
+ .fd-form .fd-section[data-row] { padding-inline-start: calc(var(--fd-row-label, 0px) + var(--fd-row-gap, 0px)); }
195
+ .fd-form .fd-section[data-row] > .fd-grid > .fd-field:first-child { grid-template-columns: minmax(0, 1fr); position: relative; }
196
+ .fd-form .fd-section[data-row] > .fd-grid > .fd-field:first-child > :not(.fd-label) { grid-column: 1; }
197
+ .fd-form .fd-section[data-row] > .fd-grid > .fd-field:first-child > .fd-label {
198
+ /* Out of the field's own box, back over the row's room for it — where the row has one. */
199
+ position: var(--fd-row-place, static); inset-inline-start: calc(-1 * (var(--fd-row-label, 0px) + var(--fd-row-gap, 0px))); inset-block-start: 0;
200
+ width: var(--fd-row-label, auto); padding-block-start: var(--fd-row-drop, 0px);
201
+ }
161
202
  /* A label beside every value needs room twice over: the underline skin stacks its columns sooner. */
162
203
  @container (max-width: 760px) {
163
204
  .fd-form[data-fd-skin="underline"] .fd-grid { --fd-cols: 1; }
@@ -169,6 +210,9 @@ const SKINS_CSS = /* css */ `
169
210
  }
170
211
  @container (max-width: 520px) {
171
212
  .fd-grid { --fd-cols: 1; }
213
+ /* Labels go above here: a row's first one too, the parts stacked under it. */
214
+ .fd-form .fd-section.fd-section[data-row] { --fd-row-label: auto; --fd-row-gap: 0px; --fd-row-place: static; --fd-row-drop: 0px; }
215
+ .fd-form .fd-section[data-row] { padding-inline-start: 0; }
172
216
  .fd-form[data-fd-skin="underline"] .fd-field:where(:not([data-labels])) { grid-template-columns: minmax(0, 1fr); }
173
217
  .fd-form[data-fd-skin="underline"] .fd-field:where(:not([data-labels])) > * { grid-column: 1 !important; }
174
218
  /* The narrow count, or one column when only the medium one was given. */
@@ -190,6 +234,8 @@ const SKINS_CSS = /* css */ `
190
234
  border-radius: var(--fd-control-radius);
191
235
  padding: var(--fd-pad-y) var(--fd-pad-x);
192
236
  min-height: var(--fd-control-height, 30px);
237
+ /* A value longer than its box ends in "…", not cut mid-letter (the whole of it shows on hover). */
238
+ text-overflow: ellipsis;
193
239
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
194
240
  }
195
241
  .fd-input::placeholder { color: var(--fd-muted); opacity: 0.8; }
@@ -199,10 +245,13 @@ const SKINS_CSS = /* css */ `
199
245
  .fd-form[data-fd-skin="underline"] .fd-input:focus { box-shadow: 0 1px 0 0 var(--fd-focus); }
200
246
  .fd-form[data-fd-skin="underline"] .fd-field.fd-required .fd-input { border-color: var(--fd-accent); }
201
247
  .fd-input[readonly] { background: transparent; border-color: transparent; padding-inline: 0; }
202
- .fd-form[data-fd-skin="outlined"] .fd-input[readonly] { background: rgba(0, 0, 0, 0.04); border-color: var(--fd-border); padding-inline: var(--fd-pad-x); color: var(--fd-muted); }
248
+ .fd-form[data-fd-skin="outlined"] .fd-input[readonly] { background: color-mix(in srgb, var(--fd-text) 5%, var(--fd-surface)); border-color: var(--fd-border); padding-inline: var(--fd-pad-x); color: var(--fd-muted); }
203
249
  /* A whole form locked reads as a record: plain values in either skin, no boxes, and no prompts to type. */
204
250
  .fd-form[data-readonly] .fd-input[readonly] { background: transparent; border-color: transparent; padding-inline: 0; color: var(--fd-text); }
205
251
  .fd-form[data-readonly] .fd-input::placeholder { color: transparent; }
252
+ /* Nothing to read in a read-only box draws nothing, in either skin: no prompt to type, and no date's dd.mm.yyyy or its calendar. */
253
+ .fd-input[readonly]::placeholder, .fd-form .fd-input.fd-blank[readonly] { color: transparent; }
254
+ .fd-blank[readonly]::-webkit-calendar-picker-indicator { display: none; }
206
255
  .fd-form[data-readonly] select.fd-input:disabled { appearance: none; background: transparent; border-color: transparent; padding-inline: 0; color: var(--fd-text); opacity: 1; }
207
256
  .fd-input[aria-invalid="true"] { border-color: var(--fd-error); }
208
257
  .fd-form[data-fd-skin="outlined"] .fd-input[aria-invalid="true"]:focus { box-shadow: 0 0 0 2px rgba(255, 38, 5, 0.06); }
@@ -272,6 +321,10 @@ const SKINS_CSS = /* css */ `
272
321
  .fd-combo-clear:hover { color: var(--fd-text); background: var(--fd-page); }
273
322
  /* A link that can be opened has its open button beside the clear button. */
274
323
  .fd-combo:has(> .fd-combo-open:not([hidden])) .fd-combo-input { padding-inline-end: 56px; }
324
+ /* Read-only, its clear button is gone: its words take the room, and an open button moves to the end. */
325
+ .fd-combo:not(.fd-choice-search .fd-combo):has(> .fd-combo-clear[hidden]) .fd-combo-input[readonly] { padding-inline-end: var(--fd-pad-x); }
326
+ .fd-combo:not(.fd-choice-search .fd-combo):has(> .fd-combo-clear[hidden]):has(> .fd-combo-open:not([hidden])) .fd-combo-input[readonly] { padding-inline-end: 30px; }
327
+ .fd-combo:has(> .fd-combo-input[readonly]) > .fd-combo-clear[hidden] ~ .fd-combo-open { inset-inline-end: 3px; }
275
328
  .fd-combo-open {
276
329
  position: absolute; inset-inline-end: 29px; border: none; background: none; cursor: pointer; color: var(--fd-accent);
277
330
  font-size: 14px; line-height: 1; padding: 0 4px; border-radius: 4px; min-width: 24px; min-height: 24px; display: inline-grid; place-items: center;
@@ -312,11 +365,97 @@ button.fd-chip-label:hover { text-decoration: underline; }
312
365
  /* A yes/no cell sits level with the inputs beside it. */
313
366
  .fd-lines-table td > .fd-checkbox, .fd-lines-table td > .fd-switch { margin-block-start: 6px; }
314
367
  .fd-lines-table .fd-lines-grip { width: 1px; min-width: 0; padding-inline: 6px 2px; }
368
+ /* A table wider than its box scrolls sideways under a line's grip and its delete button, which stay at its ends. */
369
+ .fd-lines:not([data-cards="always"]) .fd-lines-table :is(th, td):is(.fd-lines-grip, .fd-lines-tools) { position: sticky; z-index: 1; background-color: var(--fd-surface); }
370
+ .fd-lines:not([data-cards="always"]) .fd-lines-table :is(th, td).fd-lines-grip { inset-inline-start: 0; }
371
+ .fd-lines:not([data-cards="always"]) .fd-lines-table :is(th, td).fd-lines-tools { inset-inline-end: 0; }
372
+ /* A column of yes/no, numbers, money or dates as wide as its values, as Flectra's lists size them: words and links have the rest. */
373
+ .fd-lines-table td[data-fit] { min-width: 0; }
374
+ /* A head may take two lines rather than widen a column of short values: "Delivery Lead Time" over "45". */
375
+ .fd-lines-table thead th:not(.fd-lines-grip, .fd-lines-tools) { white-space: normal; }
376
+ .fd-lines-table thead th { vertical-align: bottom; }
377
+ .fd-lines-table th[data-fit="boolean"] { width: 5em; min-width: 5em; }
378
+ .fd-lines-table th[data-fit="integer"] { width: max(7em, var(--fd-fit-need, 0px)); min-width: max(7em, var(--fd-fit-need, 0px)); }
379
+ .fd-lines-table th[data-fit="float"] { width: max(7.5em, var(--fd-fit-need, 0px)); min-width: max(7.5em, var(--fd-fit-need, 0px)); }
380
+ .fd-lines-table th[data-fit="monetary"] { width: max(11.5em, var(--fd-fit-need, 0px)); min-width: max(11.5em, var(--fd-fit-need, 0px)); }
381
+ .fd-lines-table th[data-fit="date"] { width: 9em; min-width: 9em; }
382
+ .fd-lines-table th[data-fit="datetime"] { width: 12.5em; min-width: 12.5em; }
383
+ /* Numbers and money read from the end, as Flectra's lists align them. */
384
+ .fd-lines-table th:is([data-fit="integer"], [data-fit="float"], [data-fit="monetary"]) { text-align: end; }
385
+ .fd-lines-table td:is([data-fit="integer"], [data-fit="float"], [data-fit="monetary"]) input { text-align: end; }
386
+ /* A table reads as a table, as a grid does: a line shows its boxes and buttons where the pointer or the cursor is.
387
+ Only colours and visibility change, never a size: a line left for a click elsewhere must not move what is clicked.
388
+ A touch screen has no pointer to hover with: there the boxes always show. */
389
+ @media (hover: hover) and (pointer: fine) {
390
+ .fd-lines:not([data-cards="always"]) .fd-lines-table tbody tr:not(:hover, :focus-within) .fd-input:not([aria-invalid="true"]) { border-color: transparent; background-color: transparent; box-shadow: none; }
391
+ .fd-lines:not([data-cards="always"]) .fd-lines-table tbody tr:not(:hover, :focus-within) :is(.fd-combo-open, .fd-combo-clear) { visibility: hidden; }
392
+ }
315
393
  .fd-line-grip { display: block; margin-block-start: 7px; cursor: grab; }
316
- .fd-line-delete { border: none; background: none; cursor: pointer; color: var(--fd-muted); font-size: 16px; line-height: 1; padding: 4px 6px; border-radius: 4px; }
394
+ /* A line dragged by its grip follows the pointer, lifted over the others, which slide out of its way. */
395
+ .fd-lines-dragging, .fd-lines-dragging * { cursor: grabbing; user-select: none; }
396
+ .fd-lines-dragging > tr:not(.fd-line-lifted) { transition: transform 0.15s ease; }
397
+ .fd-line-lifted { position: relative; z-index: 2; box-shadow: 0 6px 18px rgba(15, 20, 25, 0.16); }
398
+ .fd-line-lifted > td { background: var(--fd-surface); }
399
+ .fd-line-delete { border: none; background: none; cursor: pointer; color: var(--fd-muted); font-size: 16px; line-height: 1; padding: 4px 6px; border-radius: 4px; min-width: 24px; min-height: 24px; }
317
400
  .fd-line-delete:hover { color: var(--fd-error); background: var(--fd-error-soft); }
401
+ /* A table's own rules: a line's or a cell's tone and bold (Flectra's decoration-*), and buttons on a line. */
402
+ .fd-lines-table [data-tone="info"] { --fd-line-tone: var(--fd-info); --fd-tone: var(--fd-info); --fd-tone-soft: var(--fd-info-soft); }
403
+ .fd-lines-table [data-tone="success"] { --fd-line-tone: var(--fd-success); --fd-tone: var(--fd-success); --fd-tone-soft: var(--fd-success-soft); }
404
+ .fd-lines-table [data-tone="warning"] { --fd-line-tone: var(--fd-warning); --fd-tone: var(--fd-warning); --fd-tone-soft: var(--fd-warning-soft); }
405
+ .fd-lines-table [data-tone="danger"] { --fd-line-tone: var(--fd-error); --fd-tone: var(--fd-error); --fd-tone-soft: var(--fd-error-soft); }
406
+ .fd-lines-table [data-tone="muted"] { --fd-line-tone: var(--fd-muted); --fd-tone: var(--fd-muted); --fd-tone-soft: color-mix(in srgb, var(--fd-muted) 14%, transparent); }
407
+ .fd-lines-table [data-tone] :is(input, select, textarea, .fd-input, .fd-display) { color: var(--fd-line-tone); -webkit-text-fill-color: var(--fd-line-tone); }
408
+ .fd-lines-table :is(.fd-line-bold, .fd-cell-bold) :is(input, select, textarea, .fd-input, .fd-display) { font-weight: 600; }
409
+ .fd-lines-table td.fd-lines-tools { white-space: nowrap; }
410
+ /* With buttons on some lines, every line's × keeps to the end, so they line up. */
411
+ .fd-lines-table:has(.fd-line-button) td.fd-lines-tools { text-align: end; padding-inline-end: 4px; }
412
+ .fd-line-button { padding: 2px 6px; font-size: 12.5px; vertical-align: middle; }
413
+ .fd-line-button-icon { padding: 4px; color: var(--fd-muted); }
414
+ .fd-line-button-icon:hover { color: var(--fd-accent); }
415
+ .fd-line-button svg { width: 15px; height: 15px; display: block; }
318
416
  .fd-lines-totals td { padding: 8px; font-weight: 600; border-block-start: 1px solid var(--fd-border); font-variant-numeric: tabular-nums; }
319
417
  .fd-lines-adds { display: flex; flex-wrap: wrap; gap: 4px 16px; justify-self: start; }
418
+ .fd-lines-control { display: inline-flex; align-items: center; gap: 6px; }
419
+ .fd-lines-control svg, .fd-lines-chosen-button svg { width: 15px; height: 15px; }
420
+ /* Lines chosen for the table's buttons: a tick before each line's grip, and a bar of buttons over the table. */
421
+ .fd-line-lead { display: inline-flex; align-items: center; gap: 4px; margin-block-start: 6px; }
422
+ .fd-line-lead .fd-line-grip { margin-block-start: 0; }
423
+ .fd-lines-table th.fd-lines-grip:has(.fd-line-pick-all) { padding-block: 4px; }
424
+ .fd-lines-chosen { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding: 6px 10px; border-radius: var(--fd-radius); background: var(--fd-accent-soft); }
425
+ .fd-lines-chosen[hidden] { display: none; }
426
+ .fd-lines-chosen-count { font-weight: 600; font-size: 13px; margin-inline-end: 6px; }
427
+ .fd-lines-chosen-button { display: inline-flex; align-items: center; gap: 6px; padding-block: 3px; }
428
+ /* A line opened in a dialog: its own record's page, or its every field. */
429
+ .fd-lines-table .fd-line-open { border: none; background: none; cursor: pointer; color: var(--fd-accent); font-size: 14px; line-height: 1; padding: 4px 6px; border-radius: 4px; }
430
+ .fd-lines-table .fd-line-open:hover { background: var(--fd-accent-soft); }
431
+ .fd-links-table td { vertical-align: middle; }
432
+ .fd-links-table .fd-value-text { padding-block: 4px; }
433
+ /* Columns as wide as they hold (fit: content), the widest taking what is left. */
434
+ .fd-lines[data-fit="content"] .fd-lines-table { width: auto; max-width: 100%; }
435
+ .fd-lines[data-fit="content"] .fd-lines-table td { min-width: 0; }
436
+ /* Lines as cards (cards: narrow on a phone, or always): each a box, every cell its column's label above its value. */
437
+ .fd-lines[data-cards] { container: fd-lines / inline-size; }
438
+ @container fd-lines (max-width: 520px) {
439
+ .fd-lines[data-cards="narrow"] .fd-lines-table, .fd-lines[data-cards="narrow"] .fd-lines-table :is(tbody, tfoot) { display: block; }
440
+ .fd-lines[data-cards="narrow"] .fd-lines-table thead { display: none; }
441
+ .fd-lines[data-cards="narrow"] .fd-lines-table tr { display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px; position: relative; padding: 10px 12px; margin-block-end: 8px; border: 1px solid var(--fd-border); border-radius: var(--fd-radius); background: var(--fd-surface); }
442
+ .fd-lines[data-cards="narrow"] .fd-lines-table td { display: block; border: none; padding: 0; min-width: 0; }
443
+ .fd-lines[data-cards="narrow"] .fd-lines-table td[data-label]:not([colspan]:not([colspan="1"]))::before { content: attr(data-label); display: block; font-size: 12px; font-weight: 600; color: var(--fd-muted); }
444
+ .fd-lines[data-cards="narrow"] .fd-lines-table td.fd-lines-grip { position: absolute; inset-block-start: 6px; inset-inline-start: 6px; padding: 0; }
445
+ .fd-lines[data-cards="narrow"] .fd-lines-table td.fd-lines-grip .fd-line-grip { display: none; }
446
+ .fd-lines[data-cards="narrow"] .fd-lines-table tr:has(.fd-line-pick) { padding-inline-start: 36px; }
447
+ .fd-lines[data-cards="narrow"] .fd-lines-table td.fd-lines-tools { width: auto; text-align: end; }
448
+ .fd-lines[data-cards="narrow"] .fd-lines-totals td:empty { display: none; }
449
+ }
450
+ .fd-lines[data-cards="always"] .fd-lines-table, .fd-lines[data-cards="always"] .fd-lines-table :is(tbody, tfoot) { display: block; }
451
+ .fd-lines[data-cards="always"] .fd-lines-table thead { display: none; }
452
+ .fd-lines[data-cards="always"] .fd-lines-table tr { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 6px 12px; position: relative; padding: 10px 12px; margin-block-end: 8px; border: 1px solid var(--fd-border); border-radius: var(--fd-radius); background: var(--fd-surface); }
453
+ .fd-lines[data-cards="always"] .fd-lines-table td { display: block; border: none; padding: 0; min-width: 0; }
454
+ .fd-lines[data-cards="always"] .fd-lines-table td[data-label]:not([colspan]:not([colspan="1"]))::before { content: attr(data-label); display: block; font-size: 12px; font-weight: 600; color: var(--fd-muted); }
455
+ .fd-lines[data-cards="always"] .fd-lines-table td.fd-lines-grip, .fd-lines[data-cards="always"] .fd-lines-table td.fd-lines-tools { grid-column: 1 / -1; width: auto; }
456
+ .fd-lines[data-cards="always"] .fd-lines-table td.fd-lines-tools { text-align: end; }
457
+ .fd-line-copy { border: none; background: none; cursor: pointer; color: var(--fd-muted); font-size: 15px; line-height: 1; padding: 4px 6px; border-radius: 4px; }
458
+ .fd-line-copy:hover { color: var(--fd-accent); background: var(--fd-accent-soft); }
320
459
  /* A section heads the lines below it; a note reads as a remark between them. */
321
460
  .fd-line-section td { background: var(--fd-page); }
322
461
  .fd-line-section .fd-input { font-weight: 600; }
@@ -433,6 +572,7 @@ button.fd-chip-label:hover { text-decoration: underline; }
433
572
  .fd-richtext-tool svg circle { fill: currentColor; stroke: none; }
434
573
  .fd-link-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; padding: 6px; border: 1px solid var(--fd-border); border-block-end: none; background: var(--fd-surface); }
435
574
  .fd-link-row > .fd-input { flex: 1 1 200px; min-width: 0; }
575
+ .fd-richtext.fd-blank[contenteditable="true"]::before { content: attr(data-placeholder); position: absolute; color: var(--fd-muted); opacity: 0.8; pointer-events: none; }
436
576
  .fd-richtext[contenteditable="false"] { background: transparent; border-color: transparent; padding-inline: 0; min-height: 0; }
437
577
  .fd-richtext p { margin: 0 0 6px; }
438
578
  .fd-code { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 12.5px; min-height: 96px; }
@@ -465,12 +605,35 @@ button.fd-chip-label:hover { text-decoration: underline; }
465
605
  /* A saved form placed in another: a quiet line while its page comes, and words in a dashed box when it cannot be shown. */
466
606
  .fd-form-part-note { margin: 0; color: var(--fd-muted); font-size: 13px; }
467
607
  .fd-form-part-problem { padding: 10px 12px; border: 1px dashed var(--fd-border); border-radius: var(--fd-radius); }
468
- .fd-tablist { display: flex; gap: 2px; border-block-end: 1px solid var(--fd-border); overflow-x: auto; }
608
+ .fd-tablist { display: flex; gap: 2px; border-block-end: 1px solid var(--fd-border); overflow-x: auto; scrollbar-width: none; }
609
+ .fd-tablist::-webkit-scrollbar { display: none; }
610
+ /* Too long for its room: the tabs fade out at an edge with more past it, under a button that scrolls them along. */
611
+ .fd-tabbar { position: relative; min-width: 0; --fd-fade: to right; }
612
+ [dir="rtl"] .fd-tabbar { --fd-fade: to left; }
613
+ /* Nothing shows under a button (28px); the tabs fade in over the next 36. */
614
+ .fd-tabbar[data-more="start"] > .fd-tablist { mask-image: linear-gradient(var(--fd-fade), transparent 28px, #000 64px); }
615
+ .fd-tabbar[data-more="end"] > .fd-tablist { mask-image: linear-gradient(var(--fd-fade), #000 calc(100% - 64px), transparent calc(100% - 28px)); }
616
+ .fd-tabbar[data-more="start end"] > .fd-tablist { mask-image: linear-gradient(var(--fd-fade), transparent 28px, #000 64px, #000 calc(100% - 64px), transparent calc(100% - 28px)); }
617
+ .fd-tabs-scroll {
618
+ position: absolute; inset-block: 0 1px; z-index: 1; width: 28px; padding: 0; border: none; background: none; cursor: pointer;
619
+ color: var(--fd-muted); display: grid; place-items: center;
620
+ }
621
+ .fd-tabs-scroll[hidden] { display: none; }
622
+ .fd-tabs-scroll:hover { color: var(--fd-accent); }
623
+ .fd-tabs-scroll::before { content: ""; width: 7px; height: 7px; border: solid currentColor; border-width: 0 0 2px 2px; }
624
+ .fd-tabs-before { inset-inline-start: 0; }
625
+ .fd-tabs-after { inset-inline-end: 0; }
626
+ .fd-tabs-before::before { transform: translateX(2px) rotate(45deg); }
627
+ .fd-tabs-after::before { transform: translateX(-2px) rotate(-135deg); }
628
+ [dir="rtl"] .fd-tabs-before::before { transform: translateX(-2px) rotate(-135deg); }
629
+ [dir="rtl"] .fd-tabs-after::before { transform: translateX(2px) rotate(45deg); }
469
630
  .fd-tab {
470
631
  font: inherit; background: none; border: none; cursor: pointer; padding: 8px 14px; color: var(--fd-muted);
471
632
  border-block-end: 2px solid transparent; margin-block-end: -1px; white-space: nowrap;
472
633
  }
473
634
  .fd-tab[aria-selected="true"] { color: var(--fd-accent); border-block-end-color: var(--fd-accent); font-weight: 600; }
635
+ /* A tab with a problem in it, seen or not: a dot in the error colour after its words. */
636
+ .fd-tab[data-problem]::after { content: ""; display: inline-block; width: 6px; height: 6px; margin-inline-start: 6px; border-radius: 50%; background: var(--fd-error); vertical-align: 0.15em; }
474
637
  .fd-tabpanel { padding-block: 16px; display: grid; gap: 16px; }
475
638
 
476
639
  /* ---- buttons ---------------------------------------------------------- */
@@ -483,7 +646,8 @@ button.fd-chip-label:hover { text-decoration: underline; }
483
646
  .fd-button-primary { background: var(--fd-accent); border-color: var(--fd-accent); color: var(--fd-accent-text); }
484
647
  .fd-button-primary:hover { color: var(--fd-accent-text); filter: brightness(1.12); }
485
648
  .fd-button-danger { color: var(--fd-error); border-color: var(--fd-error); }
486
- .fd-button-danger:hover { background: var(--fd-error); color: #fff; }
649
+ /* The surface's colour on the error's: white on a light page's deep red, near-black on a dark page's coral. */
650
+ .fd-button-danger:hover { background: var(--fd-error); color: var(--fd-surface); }
487
651
  .fd-button-link { border-color: transparent; background: none; color: var(--fd-accent); padding-inline: 4px; }
488
652
  .fd-form[data-fd-skin="underline"] .fd-button { border-radius: 3px; }
489
653
  .fd-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
@@ -515,9 +679,18 @@ button.fd-chip-label:hover { text-decoration: underline; }
515
679
  .fd-sheet-layout { align-items: start; }
516
680
  /* Save and Discard closing the sheet, when the page puts them at its foot. */
517
681
  .fd-sheet-foot { margin: 4px -28px -28px; padding: 12px 28px; border-block-start: 1px solid var(--fd-border); border-end-start-radius: inherit; border-end-end-radius: inherit; }
518
- .fd-sheet-layout.fd-has-side { grid-template-columns: minmax(0, 1fr) minmax(260px, 360px); }
519
- /* The side panel goes under the sheet before the sheet is left too narrow for a label beside its value. */
520
- @container (max-width: 1000px) { .fd-sheet-layout.fd-has-side { grid-template-columns: minmax(0, 1fr); } }
682
+ /* The side panel under the sheet, the sheet taking the whole width; beside it, as Flectra's chatter, on a form of
683
+ 1534px or more — the page growing by the panel's width, so the sheet keeps its own ("none" plus a width is no
684
+ width: a full page stays full). A page that asks keeps it beside down to 600px (record-styles). */
685
+ @container (min-width: 1534px) {
686
+ .fd-sheet-layout.fd-has-side { grid-template-columns: minmax(0, 1fr) minmax(260px, 360px); max-width: calc(var(--fd-page-max, 1180px) + 376px); }
687
+ }
688
+ .fd-sheet-layout.fd-has-side[data-side-beside="always"] { grid-template-columns: minmax(0, 1fr) minmax(260px, 360px); }
689
+ /* A part hidden at some widths of the form (hideOn): narrow up to 520px, medium up to 760px, wide above — the form's own width, as its columns. */
690
+ .fd-form { container-name: fd-form; }
691
+ @container fd-form (max-width: 520px) { .fd-form [data-hide-on~="narrow"] { display: none !important; } }
692
+ @container fd-form (min-width: 521px) and (max-width: 760px) { .fd-form [data-hide-on~="medium"] { display: none !important; } }
693
+ @container fd-form (min-width: 761px) { .fd-form [data-hide-on~="wide"] { display: none !important; } }
521
694
  .fd-card {
522
695
  position: relative; background: var(--fd-surface); border: 1px solid var(--fd-border);
523
696
  border-radius: var(--fd-radius); padding: 24px 28px 28px; display: grid; gap: 18px; min-width: 0;
@@ -527,14 +700,15 @@ button.fd-chip-label:hover { text-decoration: underline; }
527
700
  .fd-ribbon-frame { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; pointer-events: none; }
528
701
  .fd-ribbon {
529
702
  position: absolute; inset-block-start: 18px; inset-inline-end: -42px; transform: rotate(45deg); width: 160px;
530
- text-align: center; font-size: 12px; font-weight: 700; padding: 4px 0; color: #fff; background: var(--fd-muted);
703
+ text-align: center; font-size: 12px; font-weight: 700; padding: 4px 0; color: #fff; background: #5f6670;
531
704
  text-transform: uppercase; letter-spacing: 0.06em; pointer-events: none;
532
705
  }
533
706
  [dir="rtl"] .fd-ribbon { transform: rotate(-45deg); }
534
- .fd-ribbon.fd-tone-danger { background: var(--fd-error); }
535
- .fd-ribbon.fd-tone-success { background: var(--fd-success); }
536
- .fd-ribbon.fd-tone-warning { background: #d97706; }
537
- .fd-ribbon.fd-tone-info { background: var(--fd-info); }
707
+ /* White words on a ribbon in either scheme: fixed, deep colours, each at least 5:1 against white. */
708
+ .fd-ribbon.fd-tone-danger { background: #c63c3d; }
709
+ .fd-ribbon.fd-tone-success { background: #2e7d32; }
710
+ .fd-ribbon.fd-tone-warning { background: #a14f00; }
711
+ .fd-ribbon.fd-tone-info { background: #1365d9; }
538
712
  .fd-alert { padding: 10px 14px; border-radius: var(--fd-control-radius); border: 1px solid; font-size: 13.5px; display: flex; align-items: flex-start; gap: 10px; }
539
713
  .fd-alert-message { flex: 1 1 auto; min-width: 0; }
540
714
  .fd-alert-close { border: none; background: none; color: inherit; cursor: pointer; font: inherit; font-size: 18px; line-height: 1; padding: 0 4px; border-radius: 4px; opacity: 0.75; }
@@ -601,6 +775,23 @@ button.fd-chip-label:hover { text-decoration: underline; }
601
775
  .fd-progress { display: grid; gap: 8px; }
602
776
  .fd-progress-text { color: var(--fd-muted); font-size: 13px; }
603
777
  .fd-value-text { display: block; padding-block: 6px; font-variant-numeric: tabular-nums; }
778
+ /* A field's own value in a tone while a condition holds, and in bold (Flectra's decoration-* on a field). */
779
+ .fd-field[data-tone="info"] { --fd-tone: var(--fd-info); --fd-tone-soft: var(--fd-info-soft); }
780
+ .fd-field[data-tone="success"] { --fd-tone: var(--fd-success); --fd-tone-soft: var(--fd-success-soft); }
781
+ .fd-field[data-tone="warning"] { --fd-tone: var(--fd-warning); --fd-tone-soft: var(--fd-warning-soft); }
782
+ .fd-field[data-tone="danger"] { --fd-tone: var(--fd-error); --fd-tone-soft: var(--fd-error-soft); }
783
+ .fd-field[data-tone="muted"] { --fd-tone: var(--fd-muted); --fd-tone-soft: color-mix(in srgb, var(--fd-muted) 14%, transparent); }
784
+ .fd-field[data-tone] :is(input, select, textarea, .fd-value-text, .fd-pending) { color: var(--fd-tone); -webkit-text-fill-color: var(--fd-tone); }
785
+ .fd-field.fd-value-bold :is(input, select, textarea, .fd-value-text, .fd-pending, .fd-value-badge) { font-weight: 700; }
786
+ /* A value as a pill (widget badge): grey, or its tone's colour on its soft shade. */
787
+ .fd-value-badge { justify-self: start; align-self: center; display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 2px 10px; border-radius: 999px; font-size: 12.5px; line-height: 18px; font-weight: 500; color: var(--fd-tone, var(--fd-muted)); background: var(--fd-tone-soft, color-mix(in srgb, var(--fd-tone, var(--fd-muted)) 14%, transparent)); }
788
+ .fd-value-badge[hidden] { display: none; }
789
+ /* A value given its own tone by options.tones, over the part's. */
790
+ .fd-value-badge[data-tone="info"] { --fd-tone: var(--fd-info); --fd-tone-soft: var(--fd-info-soft); }
791
+ .fd-value-badge[data-tone="success"] { --fd-tone: var(--fd-success); --fd-tone-soft: var(--fd-success-soft); }
792
+ .fd-value-badge[data-tone="warning"] { --fd-tone: var(--fd-warning); --fd-tone-soft: var(--fd-warning-soft); }
793
+ .fd-value-badge[data-tone="danger"] { --fd-tone: var(--fd-error); --fd-tone-soft: var(--fd-error-soft); }
794
+ .fd-value-badge[data-tone="muted"] { --fd-tone: var(--fd-muted); --fd-tone-soft: color-mix(in srgb, var(--fd-muted) 14%, transparent); }
604
795
  .fd-date-pick { position: relative; display: flex; align-items: center; gap: 6px; min-width: 0; }
605
796
  .fd-date-pick > .fd-input { flex: 1 1 auto; min-width: 0; }
606
797
  .fd-calendar-button {
@@ -634,6 +825,9 @@ button.fd-chip-label:hover { text-decoration: underline; }
634
825
  .fd-property { display: grid; grid-template-columns: minmax(120px, 30%) minmax(0, 1fr); align-items: center; gap: 12px; min-width: 0; }
635
826
  .fd-property > label { color: var(--fd-muted); font-size: 13px; }
636
827
  .fd-property[data-type="boolean"] > :last-child { justify-self: start; }
828
+ /* Beside their values, as the sheet's labels are: the same label column, the same words, the same gap between halves — the properties read as fields of the sheet. */
829
+ .fd-form[data-fd-skin="underline"] .fd-property { grid-template-columns: var(--fd-label-width, 11em) minmax(0, 1fr); }
830
+ .fd-form[data-fd-skin="underline"] .fd-property > label { color: var(--fd-text); font-size: inherit; font-weight: var(--fd-label-weight); }
637
831
  @container (max-width: 520px) { .fd-property { grid-template-columns: minmax(0, 1fr); gap: 4px; } }
638
832
  .fd-progressbar {
639
833
  position: relative; height: 22px; min-width: 120px; border-radius: 999px; overflow: hidden;
@@ -736,9 +930,9 @@ button.fd-chip-label:hover { text-decoration: underline; }
736
930
  border: 1px solid var(--fd-edge, transparent);
737
931
  }
738
932
  .fd-dialog p { margin: 0; }
739
- /* Words a step says: toasts at the foot of the screen, one over another, each in its tone; over the page, under a dialog. */
933
+ /* Words a step says: toasts at the foot of the screen, one over another, each in its tone; over the page and over a dialog or panel, whose own words they are too. */
740
934
  .fd-says {
741
- position: fixed; inset-inline: 16px; inset-block-end: max(20px, env(safe-area-inset-bottom, 0px)); z-index: 990;
935
+ position: fixed; inset-inline: 16px; inset-block-end: max(20px, env(safe-area-inset-bottom, 0px)); z-index: 1100;
742
936
  display: grid; justify-items: center; gap: 8px; pointer-events: none;
743
937
  }
744
938
  .fd-say {
@@ -820,7 +1014,9 @@ button.fd-chip-label:hover { text-decoration: underline; }
820
1014
  @media (prefers-reduced-motion: reduce) { .fd-form *, .fd-form *::before, .fd-form *::after { transition: none !important; } .fd-button[aria-busy="true"]::after { animation: none; } }
821
1015
  `;
822
1016
  /** Fieldia's whole stylesheet: the skins, then the layout over them, the inputs' details, the question kinds and the choices' details. */
823
- exports.FIELDIA_CSS = SKINS_CSS + layout_styles_1.LAYOUT_CSS + styles_inputs_1.INPUTS_CSS + styles_kinds_1.KINDS_CSS + styles_choices_1.CHOICES_CSS + styles_parts_1.PARTS_CSS;
1017
+ // Themes' tokens after the skins' and before the page's look; their own shapes after the parts they reshape, and
1018
+ // before the page's own looks for each kind of part, which win over a theme as the page's look does.
1019
+ exports.FIELDIA_CSS = SKINS_CSS + themes_1.THEME_TOKENS_CSS + layout_styles_1.LAYOUT_CSS + styles_inputs_1.INPUTS_CSS + styles_sheet_1.SHEET_CSS + styles_business_1.BUSINESS_CSS + themes_1.THEME_RULES_CSS + styles_kinds_1.KINDS_CSS + styles_choices_1.CHOICES_CSS + styles_parts_1.PARTS_CSS;
824
1020
  const STYLE_ID = 'fieldia-styles';
825
1021
  /** Add Fieldia's stylesheet to a document, once. */
826
1022
  function installStyles(document) {
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/styles.ts"],"names":[],"mappings":";;;AA2zBA,sCAMC;AAj0BD,iDAA2C;AAC3C,qDAA+C;AAC/C,mDAA6C;AAC7C,iDAA2C;AAE3C;;;;;;;;;;;;GAYG;AACH,mDAA6C;AAE7C;;;;;GAKG;AACU,QAAA,WAAW,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAW,CAAC;AAEjE,+FAA+F;AAC/F,MAAM,SAAS,GAAG,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsxB3B,CAAC;AAEF,0IAA0I;AAC7H,QAAA,WAAW,GAAG,SAAS,GAAG,0BAAU,GAAG,0BAAU,GAAG,wBAAS,GAAG,4BAAW,GAAG,wBAAS,CAAC;AAErG,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAElC,oDAAoD;AACpD,SAAgB,aAAa,CAAC,QAAkB;IAC9C,IAAI,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC;QAAE,OAAO;IAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC;IACpB,KAAK,CAAC,WAAW,GAAG,mBAAW,CAAC;IAChC,CAAC,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC"}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/styles.ts"],"names":[],"mappings":";;;AA+/BA,sCAMC;AArgCD,iDAA2C;AAC3C,qDAA+C;AAC/C,mDAA6C;AAC7C,iDAA2C;AAC3C,iDAA2C;AAC3C,uDAAiD;AAEjD;;;;;;;;;;;;GAYG;AACH,mDAA6C;AAC7C,qCAA6D;AAE7D;;;;;GAKG;AACU,QAAA,WAAW,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAW,CAAC;AAEjE,+FAA+F;AAC/F,MAAM,SAAS,GAAG,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAq9B3B,CAAC;AAEF,0IAA0I;AAC1I,iHAAiH;AACjH,qGAAqG;AACxF,QAAA,WAAW,GAAG,SAAS,GAAG,yBAAgB,GAAG,0BAAU,GAAG,0BAAU,GAAG,wBAAS,GAAG,8BAAY,GAAG,wBAAe,GAAG,wBAAS,GAAG,4BAAW,GAAG,wBAAS,CAAC;AAErK,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAElC,oDAAoD;AACpD,SAAgB,aAAa,CAAC,QAAkB;IAC9C,IAAI,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC;QAAE,OAAO;IAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC;IACpB,KAAK,CAAC,WAAW,GAAG,mBAAW,CAAC;IAChC,CAAC,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC"}