@echelon-foundry/design-system 0.2.0 → 0.3.0-main.216.1

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 (198) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +46 -0
  3. package/dist/all.css +5537 -841
  4. package/dist/assessment.css +55 -12
  5. package/dist/build-metrics.json +181 -5
  6. package/dist/components.css +2965 -36
  7. package/dist/foundations.css +90 -0
  8. package/dist/marketing/forma-all.css +8162 -0
  9. package/dist/marketing/forma-echelon-marketing.css +2109 -0
  10. package/dist/marketing/forma-marketing-theme-echelon.css +163 -0
  11. package/dist/marketing/forma-marketing.css +1947 -0
  12. package/dist/marketing/forma-marketing.manifest.json +52 -0
  13. package/dist/marketing/forma-marketing.sha256 +4 -0
  14. package/dist/marketing.css +1198 -0
  15. package/dist/patterns/active-filter-summary.html +10 -0
  16. package/dist/patterns/attention-path.html +29 -0
  17. package/dist/patterns/badge.html +9 -0
  18. package/dist/patterns/callout.html +23 -0
  19. package/dist/patterns/card-grid.html +25 -0
  20. package/dist/patterns/character-grid-3270.html +39 -0
  21. package/dist/patterns/character-grid-field.html +21 -0
  22. package/dist/patterns/character-grid-keys.html +20 -0
  23. package/dist/patterns/character-grid-reveal.html +16 -0
  24. package/dist/patterns/character-grid-selection.html +30 -0
  25. package/dist/patterns/character-grid-status.html +11 -0
  26. package/dist/patterns/character-grid-workflow.html +147 -0
  27. package/dist/patterns/character-grid.html +16 -0
  28. package/dist/patterns/cluster.html +5 -0
  29. package/dist/patterns/code-sample.html +9 -0
  30. package/dist/patterns/command-group.html +6 -0
  31. package/dist/patterns/comparison-grid.html +7 -0
  32. package/dist/patterns/comparison-pairs.html +13 -0
  33. package/dist/patterns/cta.html +12 -0
  34. package/dist/patterns/dense-ledger.html +7 -0
  35. package/dist/patterns/diagnostic-status.html +7 -0
  36. package/dist/patterns/diagram.html +49 -0
  37. package/dist/patterns/documentation-layout.html +18 -0
  38. package/dist/patterns/emphasis-budget.html +21 -0
  39. package/dist/patterns/entry-index.html +16 -0
  40. package/dist/patterns/evidence-relationship.html +1 -0
  41. package/dist/patterns/facts.html +7 -0
  42. package/dist/patterns/fault-banner.html +19 -0
  43. package/dist/patterns/fault-blocking.html +25 -0
  44. package/dist/patterns/fault-details.html +11 -0
  45. package/dist/patterns/fault-inline.html +17 -0
  46. package/dist/patterns/fault-notification.html +20 -0
  47. package/dist/patterns/fault-reference.html +5 -0
  48. package/dist/patterns/fault-summary.html +20 -0
  49. package/dist/patterns/fault.html +17 -0
  50. package/dist/patterns/feed-item.html +12 -0
  51. package/dist/patterns/focus-stage.html +4 -0
  52. package/dist/patterns/frame.html +4 -0
  53. package/dist/patterns/freshness.html +1 -0
  54. package/dist/patterns/handoff-summary.html +1 -0
  55. package/dist/patterns/hero.html +17 -0
  56. package/dist/patterns/hierarchy-tree.html +11 -0
  57. package/dist/patterns/identifier.html +9 -0
  58. package/dist/patterns/landmark-region.html +4 -0
  59. package/dist/patterns/lane-board.html +10 -0
  60. package/dist/patterns/marketing-shell.html +40 -0
  61. package/dist/patterns/measure.html +4 -0
  62. package/dist/patterns/metric-value-change.html +9 -0
  63. package/dist/patterns/mosaic.html +6 -0
  64. package/dist/patterns/navigation-shell.html +8 -0
  65. package/dist/patterns/overflow-command-disclosure.html +6 -0
  66. package/dist/patterns/overview-disclosure.html +12 -0
  67. package/dist/patterns/path-summary.html +8 -0
  68. package/dist/patterns/priority-stack.html +4 -0
  69. package/dist/patterns/progress-bar.html +15 -0
  70. package/dist/patterns/prose.html +9 -0
  71. package/dist/patterns/rail.html +4 -0
  72. package/dist/patterns/recovery-actions.html +5 -0
  73. package/dist/patterns/relationship-index.html +8 -0
  74. package/dist/patterns/reorder-states.html +31 -0
  75. package/dist/patterns/resizable-split-pane.html +11 -0
  76. package/dist/patterns/responsive-grid.html +5 -0
  77. package/dist/patterns/scope-trail.html +1 -0
  78. package/dist/patterns/scroll-progress.html +6 -0
  79. package/dist/patterns/section-heading.html +12 -0
  80. package/dist/patterns/security-blockers.html +3 -0
  81. package/dist/patterns/security-evidence-age.html +1 -0
  82. package/dist/patterns/security-evidence-chain.html +2 -0
  83. package/dist/patterns/security-exception.html +2 -0
  84. package/dist/patterns/security-invariant-result.html +1 -0
  85. package/dist/patterns/security-posture.html +22 -0
  86. package/dist/patterns/security-state-matrix.html +5 -0
  87. package/dist/patterns/security-trend.html +1 -0
  88. package/dist/patterns/security-unknown.html +2 -0
  89. package/dist/patterns/sidebar.html +4 -0
  90. package/dist/patterns/site-footer.html +12 -0
  91. package/dist/patterns/site-header.html +18 -0
  92. package/dist/patterns/spatial-canvas.html +13 -0
  93. package/dist/patterns/spinner.html +4 -0
  94. package/dist/patterns/split-pane.html +4 -0
  95. package/dist/patterns/stack.html +5 -0
  96. package/dist/patterns/state-survivability.html +19 -0
  97. package/dist/patterns/steps.html +8 -0
  98. package/dist/patterns/switcher.html +4 -0
  99. package/dist/patterns/tooltip.html +48 -0
  100. package/dist/patterns/verification-frame.html +22 -0
  101. package/dist/patterns/workspace-shell.html +6 -0
  102. package/dist/tokens.css +436 -1
  103. package/docs/BRANDING.md +6 -1
  104. package/docs/MARKETING-SITES.md +321 -0
  105. package/figma/component-contracts.json +1544 -0
  106. package/package.json +34 -8
  107. package/patterns/active-filter-summary.html +10 -0
  108. package/patterns/aegis-faults.manifest.md +81 -0
  109. package/patterns/attention-path.html +29 -0
  110. package/patterns/badge.html +9 -0
  111. package/patterns/callout.html +23 -0
  112. package/patterns/card-grid.html +25 -0
  113. package/patterns/character-grid-3270.html +39 -0
  114. package/patterns/character-grid-field.html +21 -0
  115. package/patterns/character-grid-keys.html +20 -0
  116. package/patterns/character-grid-reveal.html +16 -0
  117. package/patterns/character-grid-selection.html +30 -0
  118. package/patterns/character-grid-status.html +11 -0
  119. package/patterns/character-grid-workflow.html +147 -0
  120. package/patterns/character-grid.html +16 -0
  121. package/patterns/cluster.html +5 -0
  122. package/patterns/code-sample.html +9 -0
  123. package/patterns/command-group.html +6 -0
  124. package/patterns/comparison-grid.html +7 -0
  125. package/patterns/comparison-pairs.html +13 -0
  126. package/patterns/cta.html +12 -0
  127. package/patterns/dense-ledger.html +7 -0
  128. package/patterns/diagnostic-status.html +7 -0
  129. package/patterns/diagram.html +49 -0
  130. package/patterns/documentation-layout.html +18 -0
  131. package/patterns/emphasis-budget.html +21 -0
  132. package/patterns/entry-index.html +16 -0
  133. package/patterns/evidence-relationship.html +1 -0
  134. package/patterns/facts.html +7 -0
  135. package/patterns/fault-banner.html +19 -0
  136. package/patterns/fault-blocking.html +25 -0
  137. package/patterns/fault-details.html +11 -0
  138. package/patterns/fault-inline.html +17 -0
  139. package/patterns/fault-notification.html +20 -0
  140. package/patterns/fault-reference.html +5 -0
  141. package/patterns/fault-summary.html +20 -0
  142. package/patterns/fault.html +17 -0
  143. package/patterns/feed-item.html +12 -0
  144. package/patterns/focus-stage.html +4 -0
  145. package/patterns/frame.html +4 -0
  146. package/patterns/freshness.html +1 -0
  147. package/patterns/handoff-summary.html +1 -0
  148. package/patterns/hero.html +17 -0
  149. package/patterns/hierarchy-tree.html +11 -0
  150. package/patterns/identifier.html +9 -0
  151. package/patterns/landmark-region.html +4 -0
  152. package/patterns/lane-board.html +10 -0
  153. package/patterns/manifest.md +2 -0
  154. package/patterns/marketing-shell.html +40 -0
  155. package/patterns/measure.html +4 -0
  156. package/patterns/metric-value-change.html +9 -0
  157. package/patterns/mosaic.html +6 -0
  158. package/patterns/navigation-shell.html +8 -0
  159. package/patterns/overflow-command-disclosure.html +6 -0
  160. package/patterns/overview-disclosure.html +12 -0
  161. package/patterns/path-summary.html +8 -0
  162. package/patterns/priority-stack.html +4 -0
  163. package/patterns/progress-bar.html +15 -0
  164. package/patterns/prose.html +9 -0
  165. package/patterns/rail.html +4 -0
  166. package/patterns/recovery-actions.html +5 -0
  167. package/patterns/relationship-index.html +8 -0
  168. package/patterns/reorder-states.html +31 -0
  169. package/patterns/resizable-split-pane.html +11 -0
  170. package/patterns/responsive-grid.html +5 -0
  171. package/patterns/scope-trail.html +1 -0
  172. package/patterns/scroll-progress.html +6 -0
  173. package/patterns/section-heading.html +12 -0
  174. package/patterns/security-blockers.html +3 -0
  175. package/patterns/security-evidence-age.html +1 -0
  176. package/patterns/security-evidence-chain.html +2 -0
  177. package/patterns/security-exception.html +2 -0
  178. package/patterns/security-invariant-result.html +1 -0
  179. package/patterns/security-posture.html +22 -0
  180. package/patterns/security-posture.manifest.md +20 -0
  181. package/patterns/security-state-matrix.html +5 -0
  182. package/patterns/security-trend.html +1 -0
  183. package/patterns/security-unknown.html +2 -0
  184. package/patterns/sidebar.html +4 -0
  185. package/patterns/site-footer.html +12 -0
  186. package/patterns/site-header.html +18 -0
  187. package/patterns/spatial-canvas.html +13 -0
  188. package/patterns/spinner.html +4 -0
  189. package/patterns/split-pane.html +4 -0
  190. package/patterns/stack.html +5 -0
  191. package/patterns/state-survivability.html +19 -0
  192. package/patterns/steps.html +8 -0
  193. package/patterns/switcher.html +4 -0
  194. package/patterns/tooltip.html +48 -0
  195. package/patterns/verification-frame.html +22 -0
  196. package/patterns/workspace-shell.html +6 -0
  197. package/schemas/brand-manifest.schema.json +17 -3
  198. package/tokens/echelon.tokens.json +2801 -0
@@ -1,3 +1,13 @@
1
+ /*
2
+ * CharacterGrid coordinates (requirements/CHARACTER-GRID.md). Registered so
3
+ * that a run's coordinates never leak to its descendants.
4
+ */
5
+ @property --ef-row { syntax: "<integer>"; inherits: false; initial-value: 1; }
6
+ @property --ef-col { syntax: "<integer>"; inherits: false; initial-value: 1; }
7
+ @property --ef-len { syntax: "<integer>"; inherits: false; initial-value: 1; }
8
+ @property --ef-height { syntax: "<integer>"; inherits: false; initial-value: 1; }
9
+ @property --ef-gutter { syntax: "<integer>"; inherits: true; initial-value: 1; }
10
+
1
11
  @layer echelon.components {
2
12
  /*
3
13
  * Public ef-* authoring tags are inert wrappers, not registered Custom
@@ -26,8 +36,37 @@
26
36
  line-height: 1.4;
27
37
  }
28
38
 
39
+ /* Motion model vocabulary --------------------------------------------- */
40
+ /*
41
+ * Every animation selects one of five canonical models before it selects
42
+ * timing (requirements/MOTION-AND-INTERACTION.md MOT-010/MOT-011; the
43
+ * machine-readable taxonomy is catalog/motion/models.json). Variables that
44
+ * do not depend on perceived mass live on the root so components,
45
+ * assessment surfaces and consuming pages share one vocabulary. Inertial
46
+ * and gravity variables are derived per component scope below because they
47
+ * depend on that scope's perceived-mass preset.
48
+ */
49
+ :where(:root) {
50
+ /* Perceptual interpolation: opacity, color, backdrop and other
51
+ non-spatial change. Deliberately independent of mass (MOT-026). */
52
+ --ef-motion-perceptual-duration: var(--ef-primitive-motion-duration-fast, 120ms);
53
+ --ef-motion-perceptual-emphasis-duration: var(--ef-primitive-motion-duration-standard, 180ms);
54
+ --ef-motion-perceptual-easing: var(--ef-primitive-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));
55
+
56
+ /* Constant-velocity cadence: repeated activity is parameterized by a
57
+ named period and constant velocity, never by spring settling (MOT-016). */
58
+ --ef-motion-cadence-period: 1600ms;
59
+ --ef-motion-cadence-rotation-period: 1000ms;
60
+ --ef-motion-cadence-easing: linear;
61
+
62
+ /* Direct manipulation / authoritative-value tracking: the visual is a
63
+ projection of the pointer, scroll or application value (MOT-002). */
64
+ --ef-motion-direct-duration: 0ms;
65
+ --ef-motion-direct-easing: linear;
66
+ }
67
+
29
68
  /* Physics-derived motion ---------------------------------------------- */
30
- :where(.ef-switch, .ef-checkbox, .ef-select, .ef-disclosure, .ef-popover, .ef-menu, .ef-dialog, .ef-flyout, .ef-tabs, .ef-alert, .ef-toast, .ef-command-palette) {
69
+ :where(.ef-switch, .ef-checkbox, .ef-select, .ef-disclosure, .ef-popover, .ef-menu, .ef-dialog, .ef-flyout, .ef-tabs, .ef-segmented, .ef-ordinal-scale, .ef-tooltip, .ef-ranking, .ef-lane-board, .ef-split-pane, .ef-alert, .ef-toast, .ef-command-palette, .ef-fault-notification, .ef-fault-banner, .ef-fault-blocking) {
31
70
  /*
32
71
  * CSS cannot run a continuous rigid-body simulation. Forma therefore uses
33
72
  * a physics-derived response model. The fallback values remain usable in
@@ -43,43 +82,48 @@
43
82
  --ef-motion-gravity-duration: 255ms;
44
83
  --ef-motion-state-duration: 154ms;
45
84
  --ef-motion-press-duration: 107ms;
46
- --ef-motion-exit-duration: 150ms;
85
+ --ef-motion-exit-duration: 146ms;
47
86
  --ef-motion-spring-easing: linear(0, 0.42 24%, 0.82 48%, 1.055 70%, 0.988 88%, 1);
48
87
  --ef-motion-damped-easing: cubic-bezier(0.2, 0.8, 0.2, 1);
49
88
  }
50
89
 
51
- :where(.ef-switch, .ef-checkbox, .ef-select, .ef-disclosure, .ef-popover, .ef-menu, .ef-dialog, .ef-flyout, .ef-tabs, .ef-alert, .ef-toast, .ef-command-palette)[data-ef-motion-weight="light"] {
90
+ :where(.ef-switch, .ef-checkbox, .ef-select, .ef-disclosure, .ef-popover, .ef-menu, .ef-dialog, .ef-flyout, .ef-tabs, .ef-segmented, .ef-ordinal-scale, .ef-tooltip, .ef-ranking, .ef-lane-board, .ef-split-pane, .ef-alert, .ef-toast, .ef-command-palette, .ef-fault-notification, .ef-fault-banner, .ef-fault-blocking)[data-ef-motion-weight="light"] {
52
91
  --ef-motion-mass: 0.65;
53
92
  --ef-motion-stiffness: 1.15;
54
93
  --ef-motion-damping: 0.94;
55
94
  }
56
95
 
57
- :where(.ef-switch, .ef-checkbox, .ef-select, .ef-disclosure, .ef-popover, .ef-menu, .ef-dialog, .ef-flyout, .ef-tabs, .ef-alert, .ef-toast, .ef-command-palette)[data-ef-motion-weight="standard"] {
96
+ :where(.ef-switch, .ef-checkbox, .ef-select, .ef-disclosure, .ef-popover, .ef-menu, .ef-dialog, .ef-flyout, .ef-tabs, .ef-segmented, .ef-ordinal-scale, .ef-tooltip, .ef-ranking, .ef-lane-board, .ef-split-pane, .ef-alert, .ef-toast, .ef-command-palette, .ef-fault-notification, .ef-fault-banner, .ef-fault-blocking)[data-ef-motion-weight="standard"] {
58
97
  --ef-motion-mass: 1;
59
98
  --ef-motion-stiffness: 1;
60
99
  --ef-motion-damping: 0.84;
61
100
  }
62
101
 
63
- :where(.ef-switch, .ef-checkbox, .ef-select, .ef-disclosure, .ef-popover, .ef-menu, .ef-dialog, .ef-flyout, .ef-tabs, .ef-alert, .ef-toast, .ef-command-palette)[data-ef-motion-weight="heavy"] {
102
+ :where(.ef-switch, .ef-checkbox, .ef-select, .ef-disclosure, .ef-popover, .ef-menu, .ef-dialog, .ef-flyout, .ef-tabs, .ef-segmented, .ef-ordinal-scale, .ef-tooltip, .ef-ranking, .ef-lane-board, .ef-split-pane, .ef-alert, .ef-toast, .ef-command-palette, .ef-fault-notification, .ef-fault-banner, .ef-fault-blocking)[data-ef-motion-weight="heavy"] {
64
103
  --ef-motion-mass: 1.8;
65
104
  --ef-motion-stiffness: 0.92;
66
105
  --ef-motion-damping: 0.76;
67
106
  }
68
107
 
69
- :where(.ef-disclosure, .ef-popover, .ef-menu, .ef-tabs):not([data-ef-motion-weight]) {
108
+ :where(.ef-disclosure, .ef-popover, .ef-menu, .ef-tabs, .ef-segmented, .ef-ordinal-scale, .ef-tooltip):not([data-ef-motion-weight]) {
70
109
  --ef-motion-mass: 0.65;
71
110
  --ef-motion-stiffness: 1.15;
72
111
  --ef-motion-damping: 0.94;
73
112
  }
74
113
 
75
- :where(.ef-dialog, .ef-flyout, .ef-command-palette):not([data-ef-motion-weight]) {
114
+ /*
115
+ * Heavy default: modal surfaces with greater spatial and attentional
116
+ * commitment (MOT-009, section 13). Alert, toast, fault notification and
117
+ * fault banner keep the standard scope default above.
118
+ */
119
+ :where(.ef-dialog, .ef-flyout, .ef-command-palette, .ef-fault-blocking):not([data-ef-motion-weight]) {
76
120
  --ef-motion-mass: 1.8;
77
121
  --ef-motion-stiffness: 0.92;
78
122
  --ef-motion-damping: 0.76;
79
123
  }
80
124
 
81
125
  @supports (width: calc(1px * sqrt(1))) {
82
- :where(.ef-switch, .ef-checkbox, .ef-select, .ef-disclosure, .ef-popover, .ef-menu, .ef-dialog, .ef-flyout, .ef-tabs, .ef-alert, .ef-toast, .ef-command-palette) {
126
+ :where(.ef-switch, .ef-checkbox, .ef-select, .ef-disclosure, .ef-popover, .ef-menu, .ef-dialog, .ef-flyout, .ef-tabs, .ef-segmented, .ef-ordinal-scale, .ef-tooltip, .ef-ranking, .ef-lane-board, .ef-split-pane, .ef-alert, .ef-toast, .ef-command-palette, .ef-fault-notification, .ef-fault-banner, .ef-fault-blocking) {
83
127
  /*
84
128
  * Response time follows sqrt(mass / stiffness), then is lengthened as
85
129
  * damping decreases. Vertical gravity time follows sqrt(2s / g) and is
@@ -156,8 +200,8 @@
156
200
  border-radius: var(--ef-primitive-radius-pill, 999px);
157
201
  background: var(--ef-color-control-track, #686d68);
158
202
  transition:
159
- background var(--ef-motion-state-duration) var(--ef-motion-damped-easing),
160
- border-color var(--ef-motion-state-duration) var(--ef-motion-damped-easing);
203
+ background var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
204
+ border-color var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing);
161
205
  }
162
206
 
163
207
  .ef-switch__track::after {
@@ -176,7 +220,7 @@
176
220
  transition:
177
221
  translate var(--ef-motion-inertia-duration) var(--ef-motion-spring-easing),
178
222
  scale var(--ef-motion-press-duration) var(--ef-motion-damped-easing),
179
- border-color var(--ef-motion-state-duration) var(--ef-motion-damped-easing);
223
+ border-color var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing);
180
224
  }
181
225
 
182
226
  .ef-switch__input:checked + .ef-switch__track {
@@ -243,8 +287,8 @@
243
287
  background: var(--ef-color-surface-primary, #f2efe7);
244
288
  scale: 1;
245
289
  transition:
246
- background var(--ef-motion-state-duration) var(--ef-motion-damped-easing),
247
- border-color var(--ef-motion-state-duration) var(--ef-motion-damped-easing),
290
+ background var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
291
+ border-color var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
248
292
  scale var(--ef-motion-press-duration) var(--ef-motion-damped-easing);
249
293
  }
250
294
 
@@ -259,7 +303,7 @@
259
303
  rotate: -12deg;
260
304
  scale: 0.35;
261
305
  transition:
262
- opacity var(--ef-motion-state-duration) linear,
306
+ opacity var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
263
307
  rotate var(--ef-motion-inertia-duration) var(--ef-motion-spring-easing),
264
308
  scale var(--ef-motion-inertia-duration) var(--ef-motion-spring-easing);
265
309
  }
@@ -320,8 +364,8 @@
320
364
  appearance: none;
321
365
  cursor: pointer;
322
366
  transition:
323
- background var(--ef-motion-state-duration) var(--ef-motion-damped-easing),
324
- border-color var(--ef-motion-state-duration) var(--ef-motion-damped-easing);
367
+ background var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
368
+ border-color var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing);
325
369
  }
326
370
 
327
371
  .ef-select__indicator {
@@ -351,7 +395,7 @@
351
395
  }
352
396
 
353
397
  @media (prefers-reduced-motion: reduce) {
354
- :where(.ef-switch, .ef-checkbox, .ef-select, .ef-disclosure, .ef-popover, .ef-menu, .ef-dialog, .ef-flyout, .ef-tabs, .ef-alert, .ef-toast, .ef-command-palette) {
398
+ :where(.ef-switch, .ef-checkbox, .ef-select, .ef-disclosure, .ef-popover, .ef-menu, .ef-dialog, .ef-flyout, .ef-tabs, .ef-segmented, .ef-ordinal-scale, .ef-tooltip, .ef-ranking, .ef-lane-board, .ef-split-pane, .ef-alert, .ef-toast, .ef-command-palette, .ef-fault-notification, .ef-fault-banner, .ef-fault-blocking) {
355
399
  --ef-motion-inertia-duration: 0.01ms;
356
400
  --ef-motion-gravity-duration: 0.01ms;
357
401
  --ef-motion-state-duration: 0.01ms;
@@ -401,9 +445,11 @@
401
445
  margin: 0;
402
446
  accent-color: var(--ef-color-control-active, #905831);
403
447
  cursor: pointer;
448
+ /* Hover/active emphasis only. The native value is direct manipulation
449
+ owned by the browser and is never transitioned (SL-MOT-001). */
404
450
  transition:
405
- filter var(--ef-primitive-motion-duration-fast, 120ms) var(--ef-primitive-motion-easing-standard, ease),
406
- opacity var(--ef-primitive-motion-duration-fast, 120ms) var(--ef-primitive-motion-easing-standard, ease);
451
+ filter var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
452
+ opacity var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing);
407
453
  }
408
454
 
409
455
  .ef-slider__input:hover { filter: saturate(1.08); }
@@ -425,8 +471,16 @@
425
471
  padding: 2px;
426
472
  border: 1px solid var(--ef-color-border-functional, #3a403c);
427
473
  background: var(--ef-color-surface-secondary, #e3e0d7);
474
+ position: relative;
475
+ isolation: isolate;
428
476
  }
429
477
 
478
+ /*
479
+ * The native radio group owns selection; the checked segment is styled
480
+ * immediately (MOT-015). Label text and background change by perceptual
481
+ * interpolation. Press compression applies to the label text layer only,
482
+ * so the hit target never moves or shrinks (MOT-014).
483
+ */
430
484
  .ef-segment {
431
485
  position: relative;
432
486
  min-block-size: 2.75rem;
@@ -438,9 +492,15 @@
438
492
  color: var(--ef-color-text-on-secondary-surface, #3a403c);
439
493
  cursor: pointer;
440
494
  transition:
441
- background var(--ef-primitive-motion-duration-fast, 120ms) var(--ef-primitive-motion-easing-standard, ease),
442
- color var(--ef-primitive-motion-duration-fast, 120ms) var(--ef-primitive-motion-easing-standard, ease),
443
- transform var(--ef-primitive-motion-duration-fast, 120ms) var(--ef-primitive-motion-easing-standard, ease);
495
+ background var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
496
+ color var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing);
497
+ }
498
+
499
+ /* scale: none at rest avoids a stacking context that would paint the
500
+ label text over the native radio; none interpolates as identity. */
501
+ .ef-segment > :not(input) {
502
+ scale: none;
503
+ transition: scale var(--ef-motion-press-duration) var(--ef-motion-damped-easing);
444
504
  }
445
505
 
446
506
  .ef-segment:has(input:checked) {
@@ -448,9 +508,51 @@
448
508
  color: var(--ef-color-text-inverse, #f2efe7);
449
509
  }
450
510
 
451
- .ef-segment:has(input:active) { transform: scale(0.985); }
511
+ .ef-segment:has(input:active:not(:disabled)) > :not(input) { scale: 0.97; }
512
+
513
+ /*
514
+ * Progressive enhancement: one selection indicator travels between
515
+ * segments with the light inertial model. anchor-scope keeps every control
516
+ * independent; without anchor positioning the checked segment's own
517
+ * background above is the complete, correct presentation. Damped easing
518
+ * (no overshoot) keeps the indicator from implying a neighbouring option.
519
+ */
520
+ @supports (anchor-name: --ef-segment) and (anchor-scope: all) {
521
+ .ef-segmented { anchor-scope: --ef-segment-selected; }
522
+
523
+ .ef-segment:has(input:checked) {
524
+ anchor-name: --ef-segment-selected;
525
+ background: transparent;
526
+ }
527
+
528
+ .ef-segmented::before {
529
+ content: "";
530
+ position: absolute;
531
+ z-index: -1;
532
+ position-anchor: --ef-segment-selected;
533
+ top: anchor(top);
534
+ right: anchor(right);
535
+ bottom: anchor(bottom);
536
+ left: anchor(left);
537
+ background: var(--ef-color-surface-inverse, #202421);
538
+ pointer-events: none;
539
+ transition:
540
+ top var(--ef-motion-inertia-duration) var(--ef-motion-damped-easing),
541
+ right var(--ef-motion-inertia-duration) var(--ef-motion-damped-easing),
542
+ bottom var(--ef-motion-inertia-duration) var(--ef-motion-damped-easing),
543
+ left var(--ef-motion-inertia-duration) var(--ef-motion-damped-easing);
544
+ }
545
+
546
+ .ef-segmented:not(:has(input:checked))::before { display: none; }
547
+ }
548
+
549
+ /* The native radio stays topmost for direct and assistive hit-testing,
550
+ including while the label text is press-compressed. */
452
551
  .ef-segment input {
552
+ z-index: 1;
453
553
  position: absolute;
554
+ inset-block-start: 0;
555
+ inset-inline-start: 0;
454
556
  inline-size: 1px;
455
557
  block-size: 1px;
456
558
  opacity: 0;
@@ -499,7 +601,7 @@
499
601
  opacity: 1;
500
602
  translate: 0 0;
501
603
  transition:
502
- opacity var(--ef-motion-state-duration) linear,
604
+ opacity var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
503
605
  translate var(--ef-motion-inertia-duration) var(--ef-motion-damped-easing);
504
606
  }
505
607
 
@@ -527,7 +629,7 @@
527
629
  translate: 0 -0.35rem;
528
630
  scale: 0.985;
529
631
  transition:
530
- opacity var(--ef-motion-exit-duration) linear,
632
+ opacity var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
531
633
  translate var(--ef-motion-exit-duration) var(--ef-motion-damped-easing),
532
634
  scale var(--ef-motion-exit-duration) var(--ef-motion-damped-easing),
533
635
  display var(--ef-motion-exit-duration) allow-discrete,
@@ -540,7 +642,7 @@
540
642
  translate: 0 0;
541
643
  scale: 1;
542
644
  transition-duration:
543
- var(--ef-motion-state-duration),
645
+ var(--ef-motion-perceptual-duration),
544
646
  var(--ef-motion-inertia-duration),
545
647
  var(--ef-motion-inertia-duration),
546
648
  var(--ef-motion-inertia-duration),
@@ -588,6 +690,200 @@
588
690
  background: var(--ef-color-surface-secondary, #e3e0d7);
589
691
  }
590
692
 
693
+ /* Tooltip / contextual hint (MOT-018, FORMA-MOT-004) ----------------- */
694
+ /*
695
+ * A supplemental hint attached to a native button. popovertarget opens it
696
+ * by click, tap, Enter or Space, and Escape or an outside press closes it,
697
+ * so no path depends on hover. Where the browser supports interest
698
+ * invokers, interestfor on the same button also opens it on hover or
699
+ * focus; the browser owns the delay and hover-travel policy. The surface
700
+ * never holds required information or an essential action.
701
+ *
702
+ * Placement uses anchor positioning with flip fallbacks where supported so
703
+ * the hint stays inside the viewport; otherwise the browser's centered
704
+ * top-layer popover placement remains readable and in view.
705
+ *
706
+ * Motion: light perceived weight. Opacity is perceptual interpolation and
707
+ * a tiny origin-related displacement is light inertial; exit uses the
708
+ * shorter derived exit duration. Reduced motion removes the displacement.
709
+ */
710
+ .ef-tooltip {
711
+ --ef-motion-distance: 0.2;
712
+ display: inline-flex;
713
+ vertical-align: middle;
714
+ }
715
+
716
+ .ef-tooltip__trigger {
717
+ min-inline-size: 2.75rem;
718
+ min-block-size: 2.75rem;
719
+ display: inline-grid;
720
+ place-items: center;
721
+ padding: 0;
722
+ border-radius: 50%;
723
+ font-family: var(--ef-primitive-font-family-mono, ui-monospace, monospace);
724
+ }
725
+
726
+ .ef-tooltip__surface {
727
+ --ef-tooltip-offset: 0.25rem;
728
+ inline-size: max-content;
729
+ max-inline-size: min(20rem, calc(100vw - 2rem));
730
+ margin: 0;
731
+ padding: 0.5rem 0.75rem;
732
+ border: 1px solid var(--ef-color-border-functional, #3a403c);
733
+ background: var(--ef-color-surface-inverse, #202421);
734
+ color: var(--ef-color-text-inverse, #f2efe7);
735
+ font-size: 0.8125rem;
736
+ line-height: 1.4;
737
+ overflow-wrap: anywhere;
738
+ opacity: 0;
739
+ translate: 0 var(--ef-tooltip-offset);
740
+ transition:
741
+ opacity var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
742
+ translate var(--ef-motion-exit-duration) var(--ef-motion-damped-easing),
743
+ display var(--ef-motion-exit-duration) allow-discrete,
744
+ overlay var(--ef-motion-exit-duration) allow-discrete;
745
+ }
746
+
747
+ .ef-tooltip__surface:popover-open {
748
+ opacity: 1;
749
+ translate: 0 0;
750
+ /* Entry settles over the light inertial duration; exit (above) uses the
751
+ shorter derived exit duration. Opacity stays perceptual both ways. */
752
+ transition-duration:
753
+ var(--ef-motion-perceptual-duration),
754
+ var(--ef-motion-inertia-duration),
755
+ var(--ef-motion-inertia-duration),
756
+ var(--ef-motion-inertia-duration);
757
+ }
758
+
759
+ @starting-style {
760
+ .ef-tooltip__surface:popover-open {
761
+ opacity: 0;
762
+ translate: 0 var(--ef-tooltip-offset);
763
+ }
764
+ }
765
+
766
+ @supports (position-area: block-start) {
767
+ .ef-tooltip__surface {
768
+ /* Spanning areas start at the invoker and extend toward one viewport
769
+ edge, so a hint near the other edge flips inward instead of
770
+ overflowing; flip-block moves it below when there is no room above. */
771
+ position-area: block-start span-inline-end;
772
+ position-try-fallbacks:
773
+ block-start span-inline-start,
774
+ block-end span-inline-end,
775
+ block-end span-inline-start;
776
+ /* Prefer whichever area leaves the hint the most room; it never grows
777
+ beyond its area, so it cannot overflow the viewport. */
778
+ position-try-order: most-inline-size;
779
+ max-inline-size: min(20rem, 100%);
780
+ margin-block-end: 0.375rem;
781
+ }
782
+ }
783
+
784
+ @media (prefers-reduced-motion: reduce) {
785
+ .ef-tooltip__surface,
786
+ .ef-tooltip__surface:popover-open {
787
+ translate: 0 0;
788
+ }
789
+ }
790
+
791
+ @media (forced-colors: active) {
792
+ .ef-tooltip__surface {
793
+ border-color: CanvasText;
794
+ background: Canvas;
795
+ color: CanvasText;
796
+ }
797
+ }
798
+
799
+ /* Progressive motion enhancements (MOT-021 to MOT-024) ----------------- */
800
+ /*
801
+ * Every enhancement below is gated behind a feature query or an explicit
802
+ * opt-in. The unenhanced presentation is the complete, correct baseline;
803
+ * no semantic state, routing, focus or consequential action depends on
804
+ * any of these animations.
805
+ */
806
+
807
+ /* Intrinsic-size disclosure (MOT-021): native details owns open/closed. */
808
+ @supports (interpolate-size: allow-keywords) and selector(::details-content) {
809
+ .ef-disclosure { interpolate-size: allow-keywords; }
810
+
811
+ .ef-disclosure::details-content {
812
+ block-size: 0;
813
+ overflow: clip;
814
+ transition:
815
+ block-size var(--ef-motion-inertia-duration) var(--ef-motion-damped-easing),
816
+ content-visibility var(--ef-motion-inertia-duration) allow-discrete;
817
+ }
818
+
819
+ .ef-disclosure[open]::details-content { block-size: auto; }
820
+ }
821
+
822
+ /*
823
+ * View Transitions (MOT-022). Opt in with data-ef-view-transitions on the
824
+ * root element. The application orchestrates document.startViewTransition()
825
+ * and must update state directly when the API is absent; snapshots are
826
+ * never semantic authority. Crossfades are perceptual interpolation;
827
+ * shared-element geometry is light inertial settling.
828
+ */
829
+ :root[data-ef-view-transitions]::view-transition-old(*),
830
+ :root[data-ef-view-transitions]::view-transition-new(*) {
831
+ animation-duration: var(--ef-motion-perceptual-emphasis-duration);
832
+ animation-timing-function: var(--ef-motion-perceptual-easing);
833
+ }
834
+
835
+ :root[data-ef-view-transitions]::view-transition-group(*) {
836
+ animation-duration: var(--ef-motion-inertia-duration, 214ms);
837
+ animation-timing-function: var(--ef-motion-damped-easing, cubic-bezier(0.2, 0.8, 0.2, 1));
838
+ }
839
+
840
+ /*
841
+ * Scroll-linked reading progress (MOT-023): a direct projection of the
842
+ * scroll position with no additional lag. Decorative only; the scrollbar and
843
+ * content remain authoritative, and nothing may be triggered from its
844
+ * visual state. Hidden where scroll timelines are unsupported, because a
845
+ * static bar could not be truthful.
846
+ */
847
+ .ef-scroll-progress {
848
+ position: sticky;
849
+ inset-block-start: 0;
850
+ z-index: 2;
851
+ display: none;
852
+ block-size: 0.1875rem;
853
+ background: var(--ef-color-accent-primary, #905831);
854
+ pointer-events: none;
855
+ }
856
+
857
+ @supports (animation-timeline: scroll()) {
858
+ .ef-scroll-progress {
859
+ display: block;
860
+ transform-origin: 0 50%;
861
+ scale: 0 1;
862
+ animation: ef-scroll-progress var(--ef-motion-direct-easing, linear) both;
863
+ animation-timeline: scroll(root block);
864
+ }
865
+
866
+ .ef-scroll-progress:dir(rtl) { transform-origin: 100% 50%; }
867
+ }
868
+
869
+ @keyframes ef-scroll-progress {
870
+ to { scale: 1 1; }
871
+ }
872
+
873
+ @media (prefers-reduced-motion: reduce) {
874
+ /* transition: none (not a near-zero duration): the discrete
875
+ content-visibility step would otherwise delay the content by frames. */
876
+ .ef-disclosure::details-content { transition: none; }
877
+
878
+ :root[data-ef-view-transitions]::view-transition-group(*),
879
+ :root[data-ef-view-transitions]::view-transition-old(*),
880
+ :root[data-ef-view-transitions]::view-transition-new(*) {
881
+ animation: none;
882
+ }
883
+
884
+ .ef-scroll-progress { display: none; }
885
+ }
886
+
591
887
  /* Dialog and flyout ---------------------------------------------------- */
592
888
  :where(.ef-dialog, .ef-flyout) {
593
889
  --ef-overlay-motion-duration: var(--ef-motion-exit-duration);
@@ -607,9 +903,10 @@
607
903
  :where(.ef-dialog, .ef-flyout)::backdrop {
608
904
  background: rgb(23 26 24 / 0);
609
905
  backdrop-filter: blur(0);
906
+ /* Dimming is non-spatial: perceptual interpolation, without mass. */
610
907
  transition:
611
- background var(--ef-overlay-motion-duration) var(--ef-motion-damped-easing),
612
- backdrop-filter var(--ef-overlay-motion-duration) var(--ef-motion-damped-easing),
908
+ background var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
909
+ backdrop-filter var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
613
910
  display var(--ef-overlay-motion-duration) allow-discrete,
614
911
  overlay var(--ef-overlay-motion-duration) allow-discrete;
615
912
  }
@@ -1001,7 +1298,7 @@
1001
1298
  background: transparent;
1002
1299
  translate: 0 0.08rem;
1003
1300
  transition:
1004
- background var(--ef-motion-state-duration) var(--ef-motion-damped-easing),
1301
+ background var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
1005
1302
  translate var(--ef-motion-inertia-duration) var(--ef-motion-spring-easing);
1006
1303
  }
1007
1304
 
@@ -1029,7 +1326,7 @@
1029
1326
  opacity: 1;
1030
1327
  translate: 0 0;
1031
1328
  transition:
1032
- opacity var(--ef-motion-state-duration) linear,
1329
+ opacity var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
1033
1330
  translate var(--ef-motion-inertia-duration) var(--ef-motion-damped-easing);
1034
1331
  }
1035
1332
 
@@ -1178,6 +1475,30 @@
1178
1475
  line-height: 1;
1179
1476
  }
1180
1477
 
1478
+ /*
1479
+ * Changing values (FORMA-MOT-011). The application writes
1480
+ * the new, authoritative value immediately; Forma never counts through
1481
+ * intermediate numbers. To mark an update, the application inserts the
1482
+ * new value element with data-ef-value-change (not on first render). The
1483
+ * text is fully legible from the first frame; only a neutral surface tint
1484
+ * fades by perceptual interpolation, identical for increases, decreases
1485
+ * and status changes, so motion implies no direction, success or severity.
1486
+ */
1487
+ :where([data-ef-value-change]) {
1488
+ background-color: transparent;
1489
+ transition: background-color var(--ef-motion-perceptual-emphasis-duration) var(--ef-motion-perceptual-easing);
1490
+ }
1491
+
1492
+ @starting-style {
1493
+ :where([data-ef-value-change]) {
1494
+ background-color: var(--ef-color-surface-secondary, #e3e0d7);
1495
+ }
1496
+ }
1497
+
1498
+ @media (prefers-reduced-motion: reduce), (forced-colors: active) {
1499
+ :where([data-ef-value-change]) { transition: none; }
1500
+ }
1501
+
1181
1502
  .ef-dashboard-grid {
1182
1503
  display: grid;
1183
1504
  grid-template-columns: repeat(3, minmax(0, 1fr));
@@ -1257,7 +1578,7 @@
1257
1578
  translate: 0 0.65rem;
1258
1579
  scale: 0.99;
1259
1580
  transition:
1260
- opacity var(--ef-motion-exit-duration) linear,
1581
+ opacity var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
1261
1582
  translate var(--ef-motion-exit-duration) var(--ef-motion-damped-easing),
1262
1583
  scale var(--ef-motion-exit-duration) var(--ef-motion-damped-easing),
1263
1584
  display var(--ef-motion-exit-duration) allow-discrete,
@@ -1269,7 +1590,7 @@
1269
1590
  translate: 0 0;
1270
1591
  scale: 1;
1271
1592
  transition-duration:
1272
- var(--ef-motion-state-duration),
1593
+ var(--ef-motion-perceptual-duration),
1273
1594
  var(--ef-motion-inertia-duration),
1274
1595
  var(--ef-motion-inertia-duration),
1275
1596
  var(--ef-motion-inertia-duration),
@@ -1328,6 +1649,7 @@
1328
1649
  border: 1px solid var(--ef-color-border-subtle, #e3e0d7);
1329
1650
  }
1330
1651
 
1652
+ /* Shimmer runs only while the application reports the activity. */
1331
1653
  .ef-skeleton__line {
1332
1654
  block-size: 0.9rem;
1333
1655
  inline-size: 100%;
@@ -1336,7 +1658,10 @@
1336
1658
  color-mix(in srgb, var(--ef-color-surface-secondary, #e3e0d7) 55%, var(--ef-color-surface-primary, #f2efe7)),
1337
1659
  var(--ef-color-surface-secondary, #e3e0d7));
1338
1660
  background-size: 200% 100%;
1339
- animation: ef-skeleton-shift 1.6s linear infinite;
1661
+ }
1662
+
1663
+ .ef-skeleton[aria-busy="true"] .ef-skeleton__line {
1664
+ animation: ef-skeleton-shift var(--ef-motion-cadence-period) var(--ef-motion-cadence-easing) infinite;
1340
1665
  }
1341
1666
 
1342
1667
  .ef-skeleton__line--title { inline-size: 55%; block-size: 1.4rem; }
@@ -1346,6 +1671,92 @@
1346
1671
  to { background-position: -200% 0; }
1347
1672
  }
1348
1673
 
1674
+ /* Loading, activity and progress (MOT-016, MOT-017) -------------------- */
1675
+ /*
1676
+ * Indeterminate activity is constant-velocity cadence: a named period and
1677
+ * linear velocity, never spring settling. Cadence never encodes expected
1678
+ * completion time or importance. Motion runs only while the application
1679
+ * reports the activity (aria-busy="true" on a skeleton, an active spinner),
1680
+ * so it stops when the activity stops. Reduced motion shows a static
1681
+ * equivalent while visible text and busy semantics continue to identify
1682
+ * the activity.
1683
+ *
1684
+ * Keep the same element in place while an activity continues: re-inserting
1685
+ * it restarts the cycle, which can read as new work. CSS cannot preserve a
1686
+ * cycle phase across re-insertion; that continuity is an application duty.
1687
+ */
1688
+ .ef-spinner {
1689
+ display: inline-flex;
1690
+ align-items: center;
1691
+ gap: var(--ef-primitive-spacing-2, 0.5rem);
1692
+ margin: 0;
1693
+ color: var(--ef-color-text-primary, #171a18);
1694
+ }
1695
+
1696
+ .ef-spinner__indicator {
1697
+ flex: 0 0 auto;
1698
+ inline-size: 1.25rem;
1699
+ block-size: 1.25rem;
1700
+ border: 2px solid currentColor;
1701
+ border-block-start-color: transparent;
1702
+ border-radius: 50%;
1703
+ }
1704
+
1705
+ .ef-spinner:not([data-ef-state="idle"]) .ef-spinner__indicator {
1706
+ animation: ef-spinner-rotate var(--ef-motion-cadence-rotation-period) var(--ef-motion-cadence-easing) infinite;
1707
+ }
1708
+
1709
+ .ef-spinner[data-ef-state="idle"] .ef-spinner__indicator {
1710
+ border-block-start-color: currentColor;
1711
+ }
1712
+
1713
+ @keyframes ef-spinner-rotate {
1714
+ to { rotate: 1turn; }
1715
+ }
1716
+
1717
+ /*
1718
+ * Determinate progress is a direct projection of the authoritative value
1719
+ * (MOT-017). The native progress element renders its value without
1720
+ * interpolation, so it can never show more than the application reports.
1721
+ * No transition is declared: an interpolation could lag or, with spring
1722
+ * easing, overshoot. The indeterminate native bar (no value) is
1723
+ * browser-owned activity presentation.
1724
+ */
1725
+ .ef-progress {
1726
+ display: grid;
1727
+ gap: var(--ef-primitive-spacing-2, 0.5rem);
1728
+ }
1729
+
1730
+ .ef-progress__header {
1731
+ min-inline-size: 0;
1732
+ display: flex;
1733
+ flex-wrap: wrap;
1734
+ justify-content: space-between;
1735
+ gap: 1rem;
1736
+ align-items: baseline;
1737
+ }
1738
+
1739
+ .ef-progress__label { font-weight: 700; }
1740
+
1741
+ .ef-progress__value {
1742
+ color: var(--ef-color-text-secondary, #686d68);
1743
+ font-family: var(--ef-primitive-font-family-mono, ui-monospace, monospace);
1744
+ font-size: 0.75rem;
1745
+ }
1746
+
1747
+ .ef-progress__bar {
1748
+ inline-size: 100%;
1749
+ block-size: 0.65rem;
1750
+ accent-color: var(--ef-color-accent-primary, #905831);
1751
+ }
1752
+
1753
+ @media (prefers-reduced-motion: reduce) {
1754
+ .ef-skeleton[aria-busy="true"] .ef-skeleton__line,
1755
+ .ef-spinner:not([data-ef-state="idle"]) .ef-spinner__indicator {
1756
+ animation: none;
1757
+ }
1758
+ }
1759
+
1349
1760
  /* Wizard and checklist ------------------------------------------------ */
1350
1761
  .ef-wizard,
1351
1762
  .ef-readiness-checklist {
@@ -1436,7 +1847,7 @@
1436
1847
  translate: 0 0.75rem;
1437
1848
  scale: 0.985;
1438
1849
  transition:
1439
- opacity var(--ef-motion-exit-duration) linear,
1850
+ opacity var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
1440
1851
  translate var(--ef-motion-exit-duration) var(--ef-motion-damped-easing),
1441
1852
  scale var(--ef-motion-exit-duration) var(--ef-motion-damped-easing),
1442
1853
  display var(--ef-motion-exit-duration) allow-discrete,
@@ -1448,7 +1859,7 @@
1448
1859
  translate: 0 0;
1449
1860
  scale: 1;
1450
1861
  transition-duration:
1451
- var(--ef-motion-state-duration),
1862
+ var(--ef-motion-perceptual-duration),
1452
1863
  var(--ef-motion-inertia-duration),
1453
1864
  var(--ef-motion-inertia-duration),
1454
1865
  var(--ef-motion-inertia-duration),
@@ -1919,6 +2330,7 @@
1919
2330
  .ef-switch__track::after,
1920
2331
  .ef-slider__input,
1921
2332
  .ef-segment,
2333
+ .ef-segment > :not(input),
1922
2334
  .ef-disclosure > summary::after,
1923
2335
  .ef-disclosure__content,
1924
2336
  .ef-popover,
@@ -1933,6 +2345,15 @@
1933
2345
  .ef-command-palette {
1934
2346
  transition-duration: 0.01ms;
1935
2347
  }
2348
+
2349
+ /* Remove spatial press compression; selection stays immediate. */
2350
+ .ef-segment:has(input:active:not(:disabled)) > :not(input) { scale: none; }
2351
+
2352
+ /* Without travel the indicator adds nothing, so reduced motion uses the
2353
+ static presentation (as in the fallback and forced colors): the checked
2354
+ segment carries its own inverse surface and the indicator is removed. */
2355
+ .ef-segmented::before { display: none; transition: none; }
2356
+ .ef-segment:has(input:checked) { background: var(--ef-color-surface-inverse, #202421); }
1936
2357
  }
1937
2358
 
1938
2359
  @media (forced-colors: active) {
@@ -1950,7 +2371,8 @@
1950
2371
  .ef-switch__track::after { background: Canvas; border-color: CanvasText; box-shadow: none; }
1951
2372
  .ef-switch__input:checked + .ef-switch__track { background: Highlight; }
1952
2373
  .ef-switch__input:checked + .ef-switch__track::after { background: HighlightText; }
1953
- .ef-segment:has(input:checked) { background: Highlight; color: HighlightText; }
2374
+ .ef-segment:has(input:checked) { forced-color-adjust: none; background: Highlight; color: HighlightText; }
2375
+ .ef-segmented::before { display: none; }
1954
2376
  }
1955
2377
 
1956
2378
  /* Agent and natural-language interaction ------------------------------- */
@@ -2121,3 +2543,2510 @@
2121
2543
  }
2122
2544
 
2123
2545
  }
2546
+
2547
+
2548
+ @layer echelon.components {
2549
+ /*
2550
+ * Aegis perceived-weight defaults live with the shared physics scope:
2551
+ * notification and banner use the standard scope default, blocking faults
2552
+ * the heavy modal default (requirements/MOTION-AND-INTERACTION.md, 13).
2553
+ */
2554
+
2555
+ /* Aegis fault presentation -------------------------------------------- */
2556
+ .ef-fault,
2557
+ .ef-fault-notification,
2558
+ .ef-fault-banner,
2559
+ .ef-fault-summary,
2560
+ .ef-diagnostic-status,
2561
+ .ef-fault-details {
2562
+ box-sizing: border-box;
2563
+ max-inline-size: 100%;
2564
+ }
2565
+
2566
+ .ef-fault {
2567
+ display: grid;
2568
+ grid-template-columns: auto minmax(0, 1fr) auto;
2569
+ align-items: start;
2570
+ gap: var(--ef-primitive-spacing-3, 0.75rem);
2571
+ padding: var(--ef-primitive-spacing-4, 1rem);
2572
+ border: 1px solid var(--ef-color-border-functional, #3a403c);
2573
+ border-inline-start-width: 0.35rem;
2574
+ background: var(--ef-color-surface-primary, #f2efe7);
2575
+ color: var(--ef-color-text-primary, #171a18);
2576
+ }
2577
+
2578
+ .ef-fault[data-ef-severity="diagnostic"] { border-inline-start-style: dotted; }
2579
+ .ef-fault[data-ef-severity="warning"] { border-inline-start-style: dashed; }
2580
+ .ef-fault[data-ef-severity="critical"] {
2581
+ border-inline-start-width: 0.55rem;
2582
+ outline: 1px solid var(--ef-color-border-functional, #3a403c);
2583
+ outline-offset: 2px;
2584
+ }
2585
+
2586
+ .ef-fault__marker,
2587
+ .ef-fault-notification__marker,
2588
+ .ef-fault-summary__marker,
2589
+ .ef-fault-blocking__marker {
2590
+ min-inline-size: 1.75rem;
2591
+ min-block-size: 1.75rem;
2592
+ display: inline-grid;
2593
+ place-items: center;
2594
+ border: 2px solid currentColor;
2595
+ border-radius: var(--ef-primitive-radius-pill, 999px);
2596
+ font-family: var(--ef-primitive-font-family-mono, ui-monospace, monospace);
2597
+ font-weight: 800;
2598
+ line-height: 1;
2599
+ }
2600
+
2601
+ .ef-fault__body,
2602
+ .ef-fault-notification__body,
2603
+ .ef-fault-banner__body {
2604
+ min-inline-size: 0;
2605
+ }
2606
+
2607
+ .ef-fault__severity {
2608
+ margin: 0 0 0.2rem;
2609
+ color: var(--ef-color-text-secondary, #686d68);
2610
+ font-family: var(--ef-primitive-font-family-mono, ui-monospace, monospace);
2611
+ font-size: 0.72rem;
2612
+ font-weight: 800;
2613
+ letter-spacing: 0.08em;
2614
+ line-height: 1.25;
2615
+ text-transform: uppercase;
2616
+ }
2617
+
2618
+ .ef-fault__title,
2619
+ .ef-fault__message,
2620
+ .ef-fault-notification p,
2621
+ .ef-fault-banner p {
2622
+ margin-block-start: 0;
2623
+ }
2624
+
2625
+ .ef-fault__title { margin-block-end: 0.35rem; }
2626
+ .ef-fault__message { margin-block-end: 0.5rem; }
2627
+
2628
+ .ef-fault-reference {
2629
+ display: flex;
2630
+ flex-wrap: wrap;
2631
+ align-items: center;
2632
+ gap: 0.4rem;
2633
+ margin: 0.55rem 0 0;
2634
+ color: var(--ef-color-text-secondary, #686d68);
2635
+ font-size: 0.8125rem;
2636
+ }
2637
+
2638
+ .ef-fault-reference code {
2639
+ color: var(--ef-color-text-primary, #171a18);
2640
+ font-weight: 750;
2641
+ overflow-wrap: anywhere;
2642
+ }
2643
+
2644
+ .ef-fault-reference button {
2645
+ min-block-size: 2.75rem;
2646
+ min-inline-size: 2.75rem;
2647
+ }
2648
+
2649
+ .ef-recovery-actions {
2650
+ display: flex;
2651
+ flex-wrap: wrap;
2652
+ align-items: center;
2653
+ gap: var(--ef-primitive-spacing-2, 0.5rem);
2654
+ min-inline-size: 0;
2655
+ }
2656
+
2657
+ .ef-recovery-actions > button,
2658
+ .ef-fault-notification__dismiss {
2659
+ min-block-size: 2.75rem;
2660
+ }
2661
+
2662
+ .ef-fault--inline {
2663
+ grid-template-columns: auto minmax(0, 1fr) auto;
2664
+ padding: 0.75rem;
2665
+ background: var(--ef-color-surface-secondary, #e3e0d7);
2666
+ }
2667
+
2668
+ .ef-fault-notification {
2669
+ --ef-motion-distance: 0.45;
2670
+ display: grid;
2671
+ grid-template-columns: auto minmax(0, 1fr) auto;
2672
+ align-items: start;
2673
+ gap: var(--ef-primitive-spacing-3, 0.75rem);
2674
+ inline-size: min(32rem, calc(100vw - 2rem));
2675
+ padding: var(--ef-primitive-spacing-4, 1rem);
2676
+ border: 1px solid var(--ef-color-border-functional, #3a403c);
2677
+ border-inline-start-width: 0.35rem;
2678
+ background: var(--ef-color-surface-primary, #f2efe7);
2679
+ color: var(--ef-color-text-primary, #171a18);
2680
+ box-shadow: 0 0.8rem 2.2rem rgb(0 0 0 / 0.18);
2681
+ opacity: 1;
2682
+ translate: 0 0;
2683
+ scale: 1;
2684
+ }
2685
+
2686
+ .ef-fault-notification[data-ef-motion-entry] {
2687
+ opacity: 1;
2688
+ translate: 0 0;
2689
+ transition:
2690
+ opacity var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
2691
+ translate var(--ef-motion-inertia-duration) var(--ef-motion-damped-easing);
2692
+ }
2693
+
2694
+ @starting-style {
2695
+ .ef-fault-notification[data-ef-motion-entry] {
2696
+ opacity: 0;
2697
+ translate: 0 -0.45rem;
2698
+ }
2699
+ }
2700
+
2701
+ .ef-fault-notification__dismiss {
2702
+ align-self: start;
2703
+ }
2704
+
2705
+ .ef-fault-banner {
2706
+ --ef-motion-distance: 0.3;
2707
+ display: grid;
2708
+ grid-template-columns: auto minmax(0, 1fr) auto;
2709
+ align-items: start;
2710
+ gap: var(--ef-primitive-spacing-3, 0.75rem);
2711
+ inline-size: 100%;
2712
+ padding: var(--ef-primitive-spacing-4, 1rem);
2713
+ border: 1px solid var(--ef-color-border-functional, #3a403c);
2714
+ border-block-width: 2px;
2715
+ }
2716
+
2717
+ .ef-fault-banner[data-ef-severity="critical"] {
2718
+ border-block-width: 3px;
2719
+ }
2720
+
2721
+ .ef-fault-banner[data-ef-motion-entry] {
2722
+ opacity: 1;
2723
+ translate: 0 0;
2724
+ transition:
2725
+ opacity var(--ef-motion-perceptual-duration) var(--ef-motion-perceptual-easing),
2726
+ translate var(--ef-motion-inertia-duration) var(--ef-motion-damped-easing);
2727
+ }
2728
+
2729
+ @starting-style {
2730
+ .ef-fault-banner[data-ef-motion-entry] {
2731
+ opacity: 0;
2732
+ translate: 0 -0.3rem;
2733
+ }
2734
+ }
2735
+
2736
+ .ef-fault-blocking {
2737
+ inline-size: min(42rem, calc(100vw - 2rem));
2738
+ max-block-size: min(90dvh, calc(100dvh - 2rem));
2739
+ }
2740
+
2741
+ .ef-fault-blocking__heading {
2742
+ display: grid;
2743
+ grid-template-columns: auto minmax(0, 1fr);
2744
+ align-items: start;
2745
+ gap: var(--ef-primitive-spacing-3, 0.75rem);
2746
+ }
2747
+
2748
+ .ef-fault-blocking__heading h2 {
2749
+ margin-block-start: 0;
2750
+ }
2751
+
2752
+ .ef-fault-summary {
2753
+ display: grid;
2754
+ gap: var(--ef-primitive-spacing-4, 1rem);
2755
+ padding: var(--ef-primitive-spacing-4, 1rem);
2756
+ border: 2px solid var(--ef-color-border-functional, #3a403c);
2757
+ background: var(--ef-color-surface-primary, #f2efe7);
2758
+ color: var(--ef-color-text-primary, #171a18);
2759
+ }
2760
+
2761
+ .ef-fault-summary:focus-visible {
2762
+ outline: 3px solid var(--ef-color-focus-gap, #f2efe7);
2763
+ outline-offset: 2px;
2764
+ box-shadow: 0 0 0 5px var(--ef-color-focus-ring, #171a18);
2765
+ }
2766
+
2767
+ .ef-fault-summary__heading {
2768
+ display: grid;
2769
+ grid-template-columns: auto minmax(0, 1fr);
2770
+ gap: var(--ef-primitive-spacing-3, 0.75rem);
2771
+ align-items: start;
2772
+ }
2773
+
2774
+ .ef-fault-summary__heading h2 {
2775
+ margin-block: 0;
2776
+ }
2777
+
2778
+ .ef-fault-summary__list {
2779
+ display: grid;
2780
+ gap: 0.65rem;
2781
+ margin: 0;
2782
+ padding-inline-start: 1.4rem;
2783
+ }
2784
+
2785
+ .ef-fault-summary__list > li {
2786
+ padding-inline-start: 0.2rem;
2787
+ }
2788
+
2789
+ .ef-fault-summary__list > li[data-ef-severity="critical"] {
2790
+ font-weight: 750;
2791
+ }
2792
+
2793
+ .ef-fault-summary__meta {
2794
+ display: block;
2795
+ margin-block-start: 0.15rem;
2796
+ color: var(--ef-color-text-secondary, #686d68);
2797
+ font-family: var(--ef-primitive-font-family-mono, ui-monospace, monospace);
2798
+ font-size: 0.75rem;
2799
+ overflow-wrap: anywhere;
2800
+ }
2801
+
2802
+ .ef-diagnostic-status {
2803
+ display: inline-flex;
2804
+ align-items: center;
2805
+ gap: var(--ef-primitive-spacing-2, 0.5rem);
2806
+ padding: 0.55rem 0.75rem;
2807
+ border: 1px solid var(--ef-color-border-functional, #3a403c);
2808
+ background: var(--ef-color-surface-secondary, #e3e0d7);
2809
+ color: var(--ef-color-text-primary, #171a18);
2810
+ }
2811
+
2812
+ .ef-diagnostic-status__marker {
2813
+ min-inline-size: 1.5rem;
2814
+ text-align: center;
2815
+ font-family: var(--ef-primitive-font-family-mono, ui-monospace, monospace);
2816
+ font-weight: 800;
2817
+ }
2818
+
2819
+ .ef-diagnostic-status__body {
2820
+ display: grid;
2821
+ gap: 0.1rem;
2822
+ }
2823
+
2824
+ .ef-diagnostic-status__body > span {
2825
+ color: var(--ef-color-text-on-secondary-surface, #3a403c);
2826
+ font-size: 0.8125rem;
2827
+ }
2828
+
2829
+ .ef-diagnostic-status[data-ef-state="unavailable"],
2830
+ .ef-diagnostic-status[data-ef-state="last-synchronization-failed"] {
2831
+ border-width: 2px;
2832
+ }
2833
+
2834
+ .ef-fault-details {
2835
+ border-block: 1px solid var(--ef-color-border-functional, #3a403c);
2836
+ }
2837
+
2838
+ .ef-fault-details > summary {
2839
+ min-block-size: 2.75rem;
2840
+ display: flex;
2841
+ align-items: center;
2842
+ cursor: pointer;
2843
+ font-weight: 700;
2844
+ }
2845
+
2846
+ .ef-fault-details__content {
2847
+ padding-block-end: var(--ef-primitive-spacing-4, 1rem);
2848
+ }
2849
+
2850
+ .ef-fault-details__list {
2851
+ display: grid;
2852
+ gap: 0.5rem;
2853
+ margin: 0;
2854
+ }
2855
+
2856
+ .ef-fault-details__list > div {
2857
+ display: grid;
2858
+ grid-template-columns: minmax(7rem, auto) minmax(0, 1fr);
2859
+ gap: 0.75rem;
2860
+ }
2861
+
2862
+ .ef-fault-details__list dt { font-weight: 700; }
2863
+ .ef-fault-details__list dd { margin: 0; overflow-wrap: anywhere; }
2864
+
2865
+ .ef-fault-details__boundary {
2866
+ margin-block-end: 0;
2867
+ color: var(--ef-color-text-secondary, #686d68);
2868
+ font-size: 0.8125rem;
2869
+ }
2870
+
2871
+ @media (max-width: 36rem) {
2872
+ .ef-fault,
2873
+ .ef-fault--inline,
2874
+ .ef-fault-notification,
2875
+ .ef-fault-banner {
2876
+ grid-template-columns: auto minmax(0, 1fr);
2877
+ }
2878
+
2879
+ .ef-fault > .ef-recovery-actions,
2880
+ .ef-fault--inline > .ef-recovery-actions,
2881
+ .ef-fault-banner > .ef-recovery-actions,
2882
+ .ef-fault-notification__dismiss {
2883
+ grid-column: 1 / -1;
2884
+ }
2885
+
2886
+ .ef-fault-notification__dismiss {
2887
+ justify-self: stretch;
2888
+ }
2889
+
2890
+ .ef-recovery-actions {
2891
+ inline-size: 100%;
2892
+ }
2893
+
2894
+ .ef-recovery-actions > button,
2895
+ .ef-fault-notification__dismiss {
2896
+ flex: 1 1 100%;
2897
+ inline-size: 100%;
2898
+ }
2899
+
2900
+ .ef-fault-details__list > div {
2901
+ grid-template-columns: 1fr;
2902
+ gap: 0.1rem;
2903
+ }
2904
+
2905
+ .ef-fault-blocking {
2906
+ inline-size: calc(100vw - 1rem);
2907
+ max-block-size: calc(100dvh - 1rem);
2908
+ margin: auto;
2909
+ }
2910
+ }
2911
+
2912
+ @media (forced-colors: active) {
2913
+ .ef-fault,
2914
+ .ef-fault-notification,
2915
+ .ef-fault-banner,
2916
+ .ef-fault-summary,
2917
+ .ef-diagnostic-status,
2918
+ .ef-fault-details {
2919
+ border-color: CanvasText;
2920
+ background: Canvas;
2921
+ color: CanvasText;
2922
+ box-shadow: none;
2923
+ }
2924
+
2925
+ .ef-fault__marker,
2926
+ .ef-fault-notification__marker,
2927
+ .ef-fault-summary__marker,
2928
+ .ef-fault-blocking__marker {
2929
+ border-color: CanvasText;
2930
+ }
2931
+
2932
+ .ef-fault__severity,
2933
+ .ef-fault-summary__meta,
2934
+ .ef-diagnostic-status__body > span,
2935
+ .ef-fault-details__boundary,
2936
+ .ef-fault-reference {
2937
+ color: CanvasText;
2938
+ }
2939
+ }
2940
+
2941
+ /* Tutela security results --------------------------------------------- */
2942
+ :where(.ef-security-posture,.ef-security-state-matrix,.ef-security-blockers,.ef-security-evidence-chain,.ef-security-unknown,.ef-security-exception) {
2943
+ min-inline-size: 0; border: 1px solid var(--ef-color-border-functional,#3a403c);
2944
+ background: var(--ef-color-surface-primary,#f2efe7); color: var(--ef-color-text-primary,#171a18);
2945
+ padding: var(--ef-primitive-spacing-4,1rem);
2946
+ }
2947
+ .ef-security-posture__header { display:flex; flex-wrap:wrap; justify-content:space-between; gap:1rem; align-items:start; }
2948
+ .ef-security-posture__eyebrow,.ef-security-unknown header p,.ef-security-exception header p { margin:0; font-size:.75rem; font-weight:700; text-transform:uppercase; letter-spacing:.06em; }
2949
+ .ef-security-posture__meta,.ef-security-unknown dl,.ef-security-exception dl { display:grid; grid-template-columns:repeat(auto-fit,minmax(min(12rem,100%),1fr)); gap:.75rem; }
2950
+ :where(.ef-security-posture__meta,.ef-security-unknown dl,.ef-security-exception dl) div { min-inline-size:0; }
2951
+ :where(.ef-security-posture__meta,.ef-security-unknown dl,.ef-security-exception dl) dt { color:var(--ef-color-text-secondary,#686d68); font-size:.75rem; font-weight:700; }
2952
+ :where(.ef-security-posture__meta,.ef-security-unknown dl,.ef-security-exception dl) dd { margin:0; overflow-wrap:anywhere; }
2953
+ .ef-security-posture__blockers,.ef-security-blockers { border-inline-start:.35rem solid currentColor; }
2954
+ .ef-security-posture__qualification { color:var(--ef-color-text-secondary,#686d68); font-size:.8125rem; }
2955
+ .ef-security-state-matrix__grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(7rem,1fr)); gap:.5rem; margin:0; }
2956
+ .ef-security-state-matrix__grid div { border-block-start:.25rem solid currentColor; padding:.75rem; background:var(--ef-color-surface-secondary,#e3e0d7); }
2957
+ .ef-security-state-matrix__grid dt { font-size:.75rem; font-weight:700; }
2958
+ .ef-security-state-matrix__grid dd { margin:0; font-size:clamp(1.4rem,4vw,2rem); font-weight:750; }
2959
+ .ef-security-blockers ul { display:grid; gap:.75rem; padding-inline-start:1.25rem; }
2960
+ .ef-security-blockers li { padding-inline-start:.25rem; }
2961
+ .ef-security-blockers li span { display:block; }
2962
+ .ef-security-evidence-chain ol { display:grid; grid-template-columns:repeat(auto-fit,minmax(9rem,1fr)); gap:.5rem; padding:0; list-style:none; }
2963
+ .ef-security-evidence-chain li { padding:.75rem; border:1px solid var(--ef-color-border-functional,#3a403c); overflow-wrap:anywhere; }
2964
+ .ef-security-evidence-chain li strong,.ef-security-evidence-chain li span,.ef-security-evidence-chain li a { display:block; }
2965
+ @media (max-width:30rem) { .ef-security-posture__header { display:grid; } .ef-security-evidence-chain ol { grid-template-columns:1fr; } }
2966
+ @media (forced-colors:active) { :where(.ef-security-posture__blockers,.ef-security-blockers,.ef-security-state-matrix__grid div) { border-color:CanvasText; } }
2967
+
2968
+ :where(.ef-invariant-result,.ef-evidence-age,.ef-security-trend) { min-inline-size:0; border:1px solid var(--ef-color-border-functional,#3a403c); padding:var(--ef-primitive-spacing-4,1rem); background:var(--ef-color-surface-primary,#f2efe7); }
2969
+ .ef-invariant-result header { display:flex; flex-wrap:wrap; align-items:baseline; gap:.5rem 1rem; }
2970
+ .ef-invariant-result header p { flex-basis:100%; margin:0; font-size:.75rem; font-weight:700; text-transform:uppercase; letter-spacing:.06em; }
2971
+ .ef-invariant-result dl { display:grid; grid-template-columns:repeat(auto-fit,minmax(min(10rem,100%),1fr)); gap:.75rem; }
2972
+ .ef-invariant-result dt { color:var(--ef-color-text-secondary,#686d68); font-size:.75rem; font-weight:700; } .ef-invariant-result dd { margin:0; overflow-wrap:anywhere; }
2973
+ :where(.ef-evidence-age,.ef-security-trend) ul { display:grid; gap:.5rem; margin:0; padding:0; list-style:none; }
2974
+ :where(.ef-evidence-age,.ef-security-trend) li { display:grid; gap:.2rem; border-inline-start:.3rem solid currentColor; padding:.65rem .75rem; background:var(--ef-color-surface-secondary,#e3e0d7); }
2975
+ :where(.ef-evidence-age,.ef-security-trend) li span { overflow-wrap:anywhere; }
2976
+
2977
+ /* Composition primitives ---------------------------------------------- */
2978
+ .ef-stack {
2979
+ --ef-stack-space: var(--ef-primitive-spacing-4, 1rem);
2980
+ display: flex;
2981
+ flex-direction: column;
2982
+ justify-content: flex-start;
2983
+ }
2984
+ .ef-stack > * { margin-block: 0; }
2985
+ .ef-stack > * + * { margin-block-start: var(--ef-stack-space); }
2986
+
2987
+ .ef-cluster {
2988
+ --ef-cluster-space: var(--ef-primitive-spacing-3, 0.75rem);
2989
+ display: flex;
2990
+ flex-wrap: wrap;
2991
+ align-items: center;
2992
+ gap: var(--ef-cluster-space);
2993
+ }
2994
+
2995
+ .ef-sidebar {
2996
+ --ef-sidebar-width: 18rem;
2997
+ --ef-sidebar-content-min: 60%;
2998
+ --ef-sidebar-space: var(--ef-primitive-spacing-5, 1.5rem);
2999
+ display: flex;
3000
+ flex-wrap: wrap;
3001
+ gap: var(--ef-sidebar-space);
3002
+ align-items: stretch;
3003
+ }
3004
+ .ef-sidebar__side {
3005
+ flex-basis: var(--ef-sidebar-width);
3006
+ flex-grow: 1;
3007
+ }
3008
+ .ef-sidebar__content {
3009
+ flex-basis: 0;
3010
+ flex-grow: 999;
3011
+ min-inline-size: min(100%, var(--ef-sidebar-content-min));
3012
+ }
3013
+
3014
+ .ef-frame {
3015
+ --ef-frame-ratio: 16 / 9;
3016
+ margin: 0;
3017
+ }
3018
+ .ef-frame__media {
3019
+ aspect-ratio: var(--ef-frame-ratio);
3020
+ overflow: hidden;
3021
+ }
3022
+ .ef-frame__media > :is(img, video, iframe, svg) {
3023
+ inline-size: 100%;
3024
+ block-size: 100%;
3025
+ object-fit: cover;
3026
+ }
3027
+
3028
+ .ef-measure {
3029
+ --ef-measure: 65ch;
3030
+ inline-size: min(100%, var(--ef-measure));
3031
+ }
3032
+
3033
+ @media (max-width: 30rem) {
3034
+ .ef-sidebar {
3035
+ display: grid;
3036
+ grid-template-columns: minmax(0, 1fr);
3037
+ }
3038
+ .ef-sidebar__side,
3039
+ .ef-sidebar__content {
3040
+ min-inline-size: 0;
3041
+ inline-size: 100%;
3042
+ }
3043
+ }
3044
+
3045
+
3046
+ .ef-landmark-region {
3047
+ --ef-landmark-space: var(--ef-primitive-spacing-3, 0.75rem);
3048
+ position: sticky;
3049
+ inset-block-start: 0;
3050
+ z-index: 1;
3051
+ display: flex;
3052
+ flex-wrap: wrap;
3053
+ align-items: center;
3054
+ justify-content: space-between;
3055
+ gap: var(--ef-landmark-space);
3056
+ padding-block: var(--ef-landmark-space);
3057
+ background: var(--ef-color-surface-primary, Canvas);
3058
+ }
3059
+ .ef-landmark-region nav {
3060
+ display: flex;
3061
+ flex-wrap: wrap;
3062
+ gap: var(--ef-landmark-space);
3063
+ }
3064
+
3065
+ .ef-split-pane {
3066
+ --ef-split-primary: minmax(0, 2fr);
3067
+ --ef-split-secondary: minmax(16rem, 1fr);
3068
+ --ef-split-space: var(--ef-primitive-spacing-5, 1.5rem);
3069
+ display: grid;
3070
+ grid-template-columns: var(--ef-split-primary) var(--ef-split-secondary);
3071
+ gap: var(--ef-split-space);
3072
+ align-items: start;
3073
+ }
3074
+ .ef-split-pane > * { min-inline-size: 0; }
3075
+
3076
+ /* Direct manipulation and post-release settling (MOT-019, MOT-020) ------ */
3077
+ /*
3078
+ * Presentation hooks only. The application or Limen owns pointer capture,
3079
+ * velocity, routing, auto-scroll, legal drop validation, resize state and
3080
+ * domain transitions, and writes the hooks below. Forma adds no lag to the
3081
+ * direct phase and never overshoots on release.
3082
+ *
3083
+ * data-ef-manipulation="dragging" | "resizing" direct phase: the visual
3084
+ * tracks --ef-drag-x/-y or
3085
+ * --ef-split-size at once
3086
+ * data-ef-manipulation="settling" | "displaced" post-release or sibling
3087
+ * movement: damped inertial
3088
+ * settling, no overshoot
3089
+ * data-ef-drop="candidate" | "accepted" | "rejected" drop presentation
3090
+ *
3091
+ * A rejected drop returns to its authoritative position (the application
3092
+ * resets the offset) and is marked with a dashed, non-color cue; its text
3093
+ * explanation belongs in the application's live region. Keyboard reorder
3094
+ * and resize write the same hooks and end in the same final state.
3095
+ */
3096
+ [data-ef-manipulation] {
3097
+ translate: var(--ef-drag-x, 0px) var(--ef-drag-y, 0px);
3098
+ transition: translate var(--ef-motion-inertia-duration, 214ms) var(--ef-motion-damped-easing, cubic-bezier(0.2, 0.8, 0.2, 1));
3099
+ }
3100
+
3101
+ [data-ef-manipulation="dragging"],
3102
+ [data-ef-manipulation="resizing"] {
3103
+ position: relative;
3104
+ z-index: 1;
3105
+ transition-duration: var(--ef-motion-direct-duration, 0ms);
3106
+ box-shadow: 0 0.6rem 1.6rem rgb(0 0 0 / 0.2);
3107
+ cursor: grabbing;
3108
+ }
3109
+
3110
+ [data-ef-drop="candidate"] {
3111
+ outline: 2px dashed var(--ef-color-accent-primary, #905831);
3112
+ outline-offset: 2px;
3113
+ }
3114
+
3115
+ [data-ef-drop="accepted"] {
3116
+ outline: 2px solid var(--ef-color-accent-primary, #905831);
3117
+ outline-offset: 2px;
3118
+ }
3119
+
3120
+ [data-ef-drop="rejected"] {
3121
+ outline: 2px dashed var(--ef-color-border-functional, #3a403c);
3122
+ outline-offset: 2px;
3123
+ background: var(--ef-color-surface-secondary, #e3e0d7);
3124
+ }
3125
+
3126
+ /*
3127
+ * Resizable split pane. --ef-split-size is the application's authoritative
3128
+ * primary size; clamp() applies the legal bounds in CSS, so neither the
3129
+ * direct phase nor settling can ever show an illegal size.
3130
+ */
3131
+ .ef-split-pane[data-ef-resizable] {
3132
+ --ef-split-size: 60%;
3133
+ --ef-split-min: 16rem;
3134
+ --ef-split-max: calc(100% - 16rem);
3135
+ grid-template-columns: clamp(var(--ef-split-min), var(--ef-split-size), var(--ef-split-max)) auto minmax(0, 1fr);
3136
+ column-gap: 0;
3137
+ transition: grid-template-columns var(--ef-motion-inertia-duration, 214ms) var(--ef-motion-damped-easing, cubic-bezier(0.2, 0.8, 0.2, 1));
3138
+ }
3139
+
3140
+ .ef-split-pane[data-ef-resizable][data-ef-manipulation] {
3141
+ translate: none;
3142
+ }
3143
+
3144
+ .ef-split-pane[data-ef-resizable][data-ef-manipulation="resizing"] {
3145
+ box-shadow: none;
3146
+ transition-duration: var(--ef-motion-direct-duration, 0ms);
3147
+ cursor: col-resize;
3148
+ }
3149
+
3150
+ /* Collapse overrides the track list itself so it wins over an inline
3151
+ application-supplied size. */
3152
+ .ef-split-pane[data-ef-resizable][data-ef-collapsed] {
3153
+ grid-template-columns: var(--ef-split-min) auto minmax(0, 1fr);
3154
+ }
3155
+
3156
+ .ef-split-pane__separator {
3157
+ align-self: stretch;
3158
+ inline-size: 2.75rem;
3159
+ min-block-size: 2.75rem;
3160
+ display: grid;
3161
+ place-items: center;
3162
+ cursor: col-resize;
3163
+ touch-action: none;
3164
+ }
3165
+
3166
+ .ef-split-pane__separator::before {
3167
+ content: "";
3168
+ inline-size: 2px;
3169
+ block-size: 100%;
3170
+ min-block-size: 2rem;
3171
+ background: var(--ef-color-border-functional, #3a403c);
3172
+ }
3173
+
3174
+ .ef-split-pane__separator:focus-visible {
3175
+ outline: 3px solid var(--ef-color-focus-gap, #f2efe7);
3176
+ outline-offset: -3px;
3177
+ box-shadow: inset 0 0 0 5px var(--ef-color-focus-ring, #171a18);
3178
+ }
3179
+
3180
+ @media (max-width: 48rem) {
3181
+ .ef-split-pane[data-ef-resizable] { grid-template-columns: minmax(0, 1fr); }
3182
+ .ef-split-pane__separator { display: none; }
3183
+ }
3184
+
3185
+ @media (prefers-reduced-motion: reduce) {
3186
+ [data-ef-manipulation],
3187
+ .ef-split-pane[data-ef-resizable] {
3188
+ transition-duration: 0.01ms;
3189
+ }
3190
+ }
3191
+
3192
+ @media (forced-colors: active) {
3193
+ [data-ef-drop] { outline-color: CanvasText; }
3194
+ .ef-split-pane__separator::before { background: CanvasText; }
3195
+ }
3196
+
3197
+ .ef-comparison-grid {
3198
+ max-inline-size: 100%;
3199
+ overflow-x: auto;
3200
+ overscroll-behavior-inline: contain;
3201
+ }
3202
+ .ef-comparison-grid table {
3203
+ inline-size: 100%;
3204
+ min-inline-size: max-content;
3205
+ border-collapse: collapse;
3206
+ }
3207
+ .ef-comparison-grid :is(th, td) {
3208
+ padding: var(--ef-primitive-spacing-3, 0.75rem);
3209
+ text-align: start;
3210
+ vertical-align: top;
3211
+ }
3212
+
3213
+ @media (max-width: 48rem) {
3214
+ .ef-split-pane { grid-template-columns: minmax(0, 1fr); }
3215
+ .ef-landmark-region { position: static; }
3216
+ }
3217
+
3218
+
3219
+ .ef-command-group {
3220
+ --ef-command-space: var(--ef-primitive-spacing-2, 0.5rem);
3221
+ display: grid;
3222
+ gap: var(--ef-command-space);
3223
+ align-content: start;
3224
+ }
3225
+ .ef-command-group__label { margin: 0; font-size: 0.875rem; }
3226
+ .ef-command-group__commands,
3227
+ .ef-overflow-commands__panel {
3228
+ display: flex;
3229
+ flex-wrap: wrap;
3230
+ gap: var(--ef-command-space, var(--ef-primitive-spacing-2, 0.5rem));
3231
+ }
3232
+ .ef-overflow-commands { position: relative; }
3233
+ .ef-overflow-commands__panel {
3234
+ padding-block-start: var(--ef-primitive-spacing-2, 0.5rem);
3235
+ }
3236
+
3237
+ .ef-switcher {
3238
+ --ef-switcher-threshold: 42rem;
3239
+ --ef-switcher-space: var(--ef-primitive-spacing-5, 1.5rem);
3240
+ display: flex;
3241
+ flex-wrap: wrap;
3242
+ gap: var(--ef-switcher-space);
3243
+ align-items: start;
3244
+ }
3245
+ .ef-switcher__primary { flex: 999 1 28rem; min-inline-size: min(100%, 20rem); }
3246
+ .ef-switcher__secondary { flex: 1 1 16rem; min-inline-size: min(100%, 16rem); }
3247
+
3248
+ .ef-workspace-shell {
3249
+ --ef-workspace-nav: minmax(10rem, 14rem);
3250
+ --ef-workspace-inspector: minmax(14rem, 20rem);
3251
+ --ef-workspace-space: var(--ef-primitive-spacing-4, 1rem);
3252
+ display: grid;
3253
+ grid-template:
3254
+ "landmark landmark landmark" auto
3255
+ "navigation primary inspector" minmax(0, 1fr)
3256
+ / var(--ef-workspace-nav) minmax(0, 1fr) var(--ef-workspace-inspector);
3257
+ gap: var(--ef-workspace-space);
3258
+ align-items: start;
3259
+ }
3260
+ .ef-workspace-shell__landmark { grid-area: landmark; }
3261
+ .ef-workspace-shell__navigation { grid-area: navigation; display: grid; gap: var(--ef-primitive-spacing-2, 0.5rem); }
3262
+ .ef-workspace-shell__primary { grid-area: primary; min-inline-size: 0; }
3263
+ .ef-workspace-shell__inspector { grid-area: inspector; min-inline-size: 0; }
3264
+
3265
+ .ef-navigation-shell {
3266
+ --ef-navigation-width: minmax(11rem, 16rem);
3267
+ --ef-navigation-space: var(--ef-primitive-spacing-4, 1rem);
3268
+ display: grid;
3269
+ grid-template-columns: var(--ef-navigation-width) minmax(0, 1fr);
3270
+ gap: var(--ef-navigation-space);
3271
+ align-items: start;
3272
+ }
3273
+ .ef-navigation-shell__persistent { display: grid; gap: var(--ef-primitive-spacing-2, 0.5rem); }
3274
+ .ef-navigation-shell__compact { display: none; }
3275
+ .ef-navigation-shell__content { min-inline-size: 0; }
3276
+
3277
+ @media (max-width: 48rem) {
3278
+ .ef-workspace-shell {
3279
+ grid-template:
3280
+ "landmark" auto
3281
+ "navigation" auto
3282
+ "primary" auto
3283
+ "inspector" auto
3284
+ / minmax(0, 1fr);
3285
+ }
3286
+ .ef-navigation-shell { grid-template-columns: minmax(0, 1fr); }
3287
+ .ef-navigation-shell__persistent { display: none; }
3288
+ .ef-navigation-shell__compact { display: block; }
3289
+ .ef-navigation-shell__compact nav { display: grid; gap: var(--ef-primitive-spacing-2, 0.5rem); padding-block-start: var(--ef-primitive-spacing-2, 0.5rem); }
3290
+ }
3291
+
3292
+ .ef-active-filter-summary { display:grid; gap:var(--ef-primitive-spacing-2,.5rem); }
3293
+ .ef-active-filter-summary__heading { display:flex; flex-wrap:wrap; gap:var(--ef-primitive-spacing-2,.5rem); align-items:center; justify-content:space-between; }
3294
+ .ef-active-filter-summary__heading h2 { margin:0; }
3295
+ .ef-active-filter-summary__items { display:flex; flex-wrap:wrap; gap:var(--ef-primitive-spacing-2,.5rem); margin:0; padding:0; list-style:none; }
3296
+ .ef-active-filter-summary__items li { display:flex; gap:var(--ef-primitive-spacing-1,.25rem); align-items:center; }
3297
+
3298
+ .ef-feed-item { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:var(--ef-primitive-spacing-2,.5rem) var(--ef-primitive-spacing-4,1rem); align-items:start; }
3299
+ .ef-feed-item__primary h2,.ef-feed-item__primary p,.ef-feed-item__summary { margin:0; }
3300
+ .ef-feed-item__meta { display:flex; flex-wrap:wrap; gap:var(--ef-primitive-spacing-2,.5rem); align-items:center; justify-content:end; }
3301
+ .ef-feed-item__summary { grid-column:1 / -1; }
3302
+ .ef-feed-item__actions { grid-column:1 / -1; }
3303
+
3304
+ .ef-lane-board { display:grid; grid-auto-flow:column; grid-auto-columns:minmax(min(18rem,85vw),1fr); gap:var(--ef-primitive-spacing-4,1rem); overflow-x:auto; overscroll-behavior-inline:contain; padding-block-end:var(--ef-primitive-spacing-2,.5rem); }
3305
+ .ef-lane-board__lane { display:grid; align-content:start; gap:var(--ef-primitive-spacing-3,.75rem); min-inline-size:0; }
3306
+ .ef-lane-board__header { display:flex; gap:var(--ef-primitive-spacing-2,.5rem); justify-content:space-between; align-items:baseline; }
3307
+ .ef-lane-board__header h2 { margin:0; }
3308
+ .ef-lane-board__items { display:grid; gap:var(--ef-primitive-spacing-2,.5rem); margin:0; padding:0; list-style:none; }
3309
+
3310
+ .ef-spatial-canvas { display:grid; gap:var(--ef-primitive-spacing-3,.75rem); min-inline-size:0; }
3311
+ .ef-spatial-canvas__header { display:flex; flex-wrap:wrap; gap:var(--ef-primitive-spacing-3,.75rem); justify-content:space-between; align-items:start; }
3312
+ .ef-spatial-canvas__header h2,.ef-spatial-canvas__orientation { margin:0; }
3313
+ .ef-spatial-canvas__viewport { overflow:auto; max-inline-size:100%; min-block-size:18rem; border:1px solid currentColor; }
3314
+ .ef-spatial-canvas__surface { min-inline-size:48rem; min-block-size:28rem; display:grid; grid-template-columns:repeat(3,minmax(12rem,1fr)); gap:var(--ef-primitive-spacing-6,2rem); padding:var(--ef-primitive-spacing-5,1.5rem); align-content:start; }
3315
+ .ef-spatial-canvas__index nav { display:flex; flex-wrap:wrap; gap:var(--ef-primitive-spacing-3,.75rem); padding-block-start:var(--ef-primitive-spacing-2,.5rem); }
3316
+
3317
+ @media (max-width:30rem) {
3318
+ .ef-feed-item { grid-template-columns:minmax(0,1fr); }
3319
+ .ef-feed-item__meta { justify-content:start; }
3320
+ }
3321
+
3322
+ .ef-scope-trail ol { display:flex; flex-wrap:wrap; gap:var(--ef-primitive-spacing-1,.25rem) var(--ef-primitive-spacing-2,.5rem); margin:0; padding:0; list-style:none; }
3323
+ .ef-scope-trail li + li::before { content:"/"; margin-inline-end:var(--ef-primitive-spacing-2,.5rem); }
3324
+
3325
+ .ef-evidence-relationship { display:grid; gap:var(--ef-primitive-spacing-3,.75rem); }
3326
+ .ef-evidence-relationship header > :last-child,.ef-evidence-relationship__body > :last-child { margin-block-end:0; }
3327
+ .ef-evidence-relationship__body { display:grid; gap:var(--ef-primitive-spacing-2,.5rem); }
3328
+
3329
+ .ef-freshness { display:flex; flex-wrap:wrap; gap:var(--ef-primitive-spacing-1,.25rem) var(--ef-primitive-spacing-2,.5rem); align-items:baseline; }
3330
+ .ef-freshness__label { font-weight:600; }
3331
+
3332
+ .ef-handoff-summary { display:grid; gap:var(--ef-primitive-spacing-4,1rem); }
3333
+ .ef-handoff-summary dl { display:grid; gap:var(--ef-primitive-spacing-3,.75rem); margin:0; }
3334
+ .ef-handoff-summary dl > div { display:grid; grid-template-columns:minmax(9rem,12rem) minmax(0,1fr); gap:var(--ef-primitive-spacing-3,.75rem); }
3335
+ .ef-handoff-summary dt { font-weight:600; }
3336
+ .ef-handoff-summary dd { margin:0; }
3337
+ @media (max-width:30rem) { .ef-handoff-summary dl > div { grid-template-columns:minmax(0,1fr); gap:var(--ef-primitive-spacing-1,.25rem); } }
3338
+
3339
+
3340
+
3341
+ /* Visual Engineering verification and low-context content ------------- */
3342
+ .ef-identifier,
3343
+ .ef-critical-value {
3344
+ font-family: var(--ef-primitive-font-family-mono, ui-monospace, "SFMono-Regular", Consolas, monospace);
3345
+ font-variant-numeric: tabular-nums slashed-zero;
3346
+ font-feature-settings: "tnum" 1, "zero" 1;
3347
+ letter-spacing: 0.015em;
3348
+ overflow-wrap: anywhere;
3349
+ }
3350
+ .ef-identifier { font-size: 0.9375em; }
3351
+ .ef-critical-value { font-weight: 750; }
3352
+ .ef-critical-value[data-ef-verify="true"] {
3353
+ display: inline-block;
3354
+ padding-inline: 0.25em;
3355
+ border-block-end: 0.15em double currentColor;
3356
+ }
3357
+
3358
+ .ef-verification-frame {
3359
+ display: grid;
3360
+ gap: var(--ef-primitive-spacing-4, 1rem);
3361
+ border: 1px solid var(--ef-color-border-functional, #3a403c);
3362
+ background: var(--ef-color-surface-primary, #f2efe7);
3363
+ }
3364
+ .ef-verification-frame__recognize,
3365
+ .ef-verification-frame__verify,
3366
+ .ef-verification-frame__act {
3367
+ padding: var(--ef-primitive-spacing-4, 1rem);
3368
+ }
3369
+ .ef-verification-frame__recognize {
3370
+ display: grid;
3371
+ gap: var(--ef-primitive-spacing-2, 0.5rem);
3372
+ border-block-end: 1px solid var(--ef-color-border-subtle, #e3e0d7);
3373
+ }
3374
+ .ef-verification-frame__recognize > :is(h2, h3, p),
3375
+ .ef-verification-frame__verify > :first-child,
3376
+ .ef-verification-frame__act > :first-child { margin-block-start: 0; }
3377
+ .ef-verification-frame__recognize > :last-child,
3378
+ .ef-verification-frame__verify > :last-child,
3379
+ .ef-verification-frame__act > :last-child { margin-block-end: 0; }
3380
+ .ef-verification-frame__verify {
3381
+ display: grid;
3382
+ gap: var(--ef-primitive-spacing-3, 0.75rem);
3383
+ }
3384
+ .ef-verification-frame__facts {
3385
+ display: grid;
3386
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
3387
+ gap: var(--ef-primitive-spacing-3, 0.75rem);
3388
+ margin: 0;
3389
+ }
3390
+ .ef-verification-frame__facts > div {
3391
+ min-inline-size: 0;
3392
+ padding-block: var(--ef-primitive-spacing-2, 0.5rem);
3393
+ border-block-end: 1px solid var(--ef-color-border-subtle, #e3e0d7);
3394
+ }
3395
+ .ef-verification-frame__facts dt {
3396
+ color: var(--ef-color-text-secondary, #686d68);
3397
+ font-size: 0.75rem;
3398
+ font-weight: 700;
3399
+ }
3400
+ .ef-verification-frame__facts dd { margin: 0.25rem 0 0; }
3401
+ .ef-verification-frame__act {
3402
+ display: flex;
3403
+ flex-wrap: wrap;
3404
+ gap: var(--ef-primitive-spacing-2, 0.5rem);
3405
+ align-items: center;
3406
+ border-block-start: 1px solid var(--ef-color-border-subtle, #e3e0d7);
3407
+ }
3408
+ .ef-verification-frame__act > p { flex: 1 1 18rem; }
3409
+ @media (max-width: 30rem) {
3410
+ .ef-verification-frame__act { align-items: stretch; }
3411
+ .ef-verification-frame__act > :is(button, .ef-button) { inline-size: 100%; }
3412
+ }
3413
+ @media (forced-colors: active) {
3414
+ .ef-critical-value[data-ef-verify="true"],
3415
+ .ef-verification-frame { border-color: CanvasText; }
3416
+ }
3417
+
3418
+ .ef-relationship-index,.ef-path-summary { display:grid; gap:var(--ef-primitive-spacing-3,.75rem); }
3419
+ .ef-relationship-index header > :last-child,.ef-path-summary header > :last-child { margin-block-end:0; }
3420
+ .ef-relationship-index__list { display:grid; gap:var(--ef-primitive-spacing-2,.5rem); margin:0; }
3421
+ .ef-relationship-index__list > div { display:grid; grid-template-columns:minmax(7rem,10rem) minmax(0,1fr); gap:var(--ef-primitive-spacing-3,.75rem); }
3422
+ .ef-relationship-index__list dt { font-weight:600; }
3423
+ .ef-relationship-index__list dd { margin:0; }
3424
+
3425
+ .ef-path-summary__steps { display:grid; gap:var(--ef-primitive-spacing-2,.5rem); margin:0; padding-inline-start:1.5rem; }
3426
+ .ef-path-summary__steps li { padding-inline-start:var(--ef-primitive-spacing-1,.25rem); }
3427
+ .ef-path-summary__steps span { display:block; }
3428
+
3429
+ .ef-hierarchy-tree ul { list-style:none; margin:0; padding-inline-start:var(--ef-primitive-spacing-4,1rem); }
3430
+ .ef-hierarchy-tree > ul { padding-inline-start:0; }
3431
+ .ef-hierarchy-tree li { margin-block:var(--ef-primitive-spacing-1,.25rem); }
3432
+ .ef-hierarchy-tree summary,.ef-hierarchy-tree a { min-block-size:2.75rem; display:flex; align-items:center; }
3433
+ .ef-hierarchy-tree [aria-current="page"] { font-weight:700; }
3434
+
3435
+ @media (max-width:30rem) {
3436
+ .ef-relationship-index__list > div { grid-template-columns:minmax(0,1fr); gap:var(--ef-primitive-spacing-1,.25rem); }
3437
+ .ef-hierarchy-tree ul { padding-inline-start:var(--ef-primitive-spacing-2,.5rem); }
3438
+ }
3439
+
3440
+ /* Composition stress hardening */
3441
+ .ef-navigation-shell__compact > summary { min-block-size:2.75rem; display:flex; align-items:center; cursor:pointer; }
3442
+ .ef-lane-board { max-inline-size:100%; }
3443
+ .ef-lane-board:focus-visible,.ef-comparison-grid:focus-visible,.ef-spatial-canvas__viewport:focus-visible { outline:2px solid currentColor; outline-offset:2px; }
3444
+ .ef-search,.ef-search__control,.ef-active-filter-summary,.ef-active-filter-summary__items,.ef-active-filter-summary__items li { min-inline-size:0; }
3445
+ .ef-search input { min-inline-size:0; max-inline-size:100%; }
3446
+ @media (max-width:30rem) {
3447
+ .ef-search__control { display:grid; grid-template-columns:minmax(0,1fr); }
3448
+ .ef-active-filter-summary__items li { flex-wrap:wrap; }
3449
+ }
3450
+
3451
+ /* Text and target-size resilience from conformance evidence */
3452
+ .ef-overflow-commands > summary {
3453
+ min-block-size:2.75rem;
3454
+ display:flex;
3455
+ align-items:center;
3456
+ cursor:pointer;
3457
+ }
3458
+ .ef-verification-frame,
3459
+ .ef-verification-frame__recognize,
3460
+ .ef-verification-frame__verify,
3461
+ .ef-verification-frame__act,
3462
+ .ef-verification-frame__facts,
3463
+ .ef-verification-frame__facts > div {
3464
+ min-inline-size:0;
3465
+ max-inline-size:100%;
3466
+ }
3467
+ .ef-verification-frame :is(h2,h3,p,dt,dd,button) { overflow-wrap:anywhere; }
3468
+ @media (max-width:30rem) {
3469
+ .ef-verification-frame__act {
3470
+ display:grid;
3471
+ grid-template-columns:minmax(0,1fr);
3472
+ }
3473
+ .ef-verification-frame__act > * {
3474
+ min-inline-size:0;
3475
+ max-inline-size:100%;
3476
+ inline-size:100%;
3477
+ }
3478
+ .ef-verification-frame__act > button {
3479
+ white-space:normal;
3480
+ block-size:auto;
3481
+ min-block-size:2.75rem;
3482
+ }
3483
+ }
3484
+
3485
+
3486
+
3487
+ /* Visual Engineering comparison, overview, and state survivability ----- */
3488
+ .ef-comparison-pairs {
3489
+ display: grid;
3490
+ gap: var(--ef-primitive-spacing-4, 1rem);
3491
+ }
3492
+ .ef-comparison-pairs__item {
3493
+ display: grid;
3494
+ grid-template-columns: minmax(8rem, 0.8fr) repeat(2, minmax(0, 1fr));
3495
+ gap: var(--ef-primitive-spacing-2, 0.5rem) var(--ef-primitive-spacing-4, 1rem);
3496
+ padding-block: var(--ef-primitive-spacing-3, 0.75rem);
3497
+ border-block-end: 1px solid var(--ef-color-border-subtle, #e3e0d7);
3498
+ }
3499
+ .ef-comparison-pairs__label { font-weight: 700; }
3500
+ .ef-comparison-pairs__value { min-inline-size: 0; overflow-wrap: anywhere; }
3501
+ .ef-comparison-pairs__value::before {
3502
+ display: block;
3503
+ margin-block-end: 0.2rem;
3504
+ color: var(--ef-color-text-secondary, #686d68);
3505
+ font-size: 0.75rem;
3506
+ font-weight: 700;
3507
+ }
3508
+ .ef-comparison-pairs__value[data-side="before"]::before { content: attr(data-label); }
3509
+ .ef-comparison-pairs__value[data-side="after"]::before { content: attr(data-label); }
3510
+
3511
+ .ef-overview-disclosure {
3512
+ display: grid;
3513
+ gap: var(--ef-primitive-spacing-3, 0.75rem);
3514
+ }
3515
+ .ef-overview-disclosure__overview {
3516
+ display: grid;
3517
+ gap: var(--ef-primitive-spacing-2, 0.5rem);
3518
+ padding: var(--ef-primitive-spacing-3, 0.75rem);
3519
+ border-inline-start: 0.25rem solid currentColor;
3520
+ }
3521
+ .ef-overview-disclosure__overview > :first-child,
3522
+ .ef-overview-disclosure__overview > :last-child { margin-block: 0; }
3523
+
3524
+ .ef-state-survivability {
3525
+ display: grid;
3526
+ gap: var(--ef-primitive-spacing-3, 0.75rem);
3527
+ }
3528
+ .ef-state-survivability__state {
3529
+ display: grid;
3530
+ grid-template-columns: minmax(8rem, auto) minmax(0, 1fr);
3531
+ gap: var(--ef-primitive-spacing-3, 0.75rem);
3532
+ align-items: start;
3533
+ padding-block: var(--ef-primitive-spacing-2, 0.5rem);
3534
+ border-block-end: 1px solid var(--ef-color-border-subtle, #e3e0d7);
3535
+ }
3536
+ .ef-state-survivability__state p { margin: 0; }
3537
+
3538
+ @media (max-width: 30rem) {
3539
+ .ef-comparison-pairs__item,
3540
+ .ef-state-survivability__state {
3541
+ grid-template-columns: minmax(0, 1fr);
3542
+ }
3543
+ }
3544
+
3545
+
3546
+
3547
+ /* Visual Engineering attention-path composition ------------------------ */
3548
+ .ef-attention-path {
3549
+ display: grid;
3550
+ gap: var(--ef-primitive-spacing-4, 1rem);
3551
+ }
3552
+ .ef-attention-path__primary {
3553
+ display: grid;
3554
+ gap: var(--ef-primitive-spacing-2, 0.5rem);
3555
+ padding: var(--ef-primitive-spacing-4, 1rem);
3556
+ border: 2px solid var(--ef-color-border-functional, #3a403c);
3557
+ background: var(--ef-color-surface-primary, #f2efe7);
3558
+ }
3559
+ .ef-attention-path__primary > :first-child,
3560
+ .ef-attention-path__primary > :last-child { margin-block: 0; }
3561
+ .ef-attention-path__support {
3562
+ display: grid;
3563
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
3564
+ gap: var(--ef-primitive-spacing-4, 1rem);
3565
+ }
3566
+ .ef-attention-path__support > * {
3567
+ min-inline-size: 0;
3568
+ padding: var(--ef-primitive-spacing-3, 0.75rem);
3569
+ border-block-start: 1px solid var(--ef-color-border-subtle, #e3e0d7);
3570
+ }
3571
+ .ef-attention-path [data-attention-step] {
3572
+ position: relative;
3573
+ }
3574
+ .ef-attention-path [data-attention-step]::before {
3575
+ content: "Priority " attr(data-attention-step);
3576
+ display: block;
3577
+ margin-block-end: 0.35rem;
3578
+ color: var(--ef-color-text-secondary, #686d68);
3579
+ font-family: var(--ef-primitive-font-family-mono, ui-monospace, monospace);
3580
+ font-size: 0.6875rem;
3581
+ font-weight: 700;
3582
+ letter-spacing: 0.04em;
3583
+ text-transform: uppercase;
3584
+ }
3585
+ @media (forced-colors: active) {
3586
+ .ef-attention-path__primary { border-color: CanvasText; background: Canvas; color: CanvasText; }
3587
+ .ef-attention-path__support > * { border-color: CanvasText; }
3588
+ }
3589
+
3590
+ /* Attention and spatial resilience from conformance evidence */
3591
+ .ef-spatial-canvas__index > summary {
3592
+ min-block-size:2.75rem;
3593
+ display:flex;
3594
+ align-items:center;
3595
+ cursor:pointer;
3596
+ }
3597
+ .ef-attention-path,
3598
+ .ef-attention-path > *,
3599
+ .ef-attention-path__primary,
3600
+ .ef-attention-path__support,
3601
+ .ef-attention-path__support > * {
3602
+ min-inline-size:0;
3603
+ max-inline-size:100%;
3604
+ }
3605
+ .ef-attention-path :is(h2,h3,p,button,.ef-status-lozenge) { overflow-wrap:anywhere; }
3606
+ @media (max-width:30rem) {
3607
+ .ef-attention-path__primary .ef-cluster {
3608
+ display:grid;
3609
+ grid-template-columns:minmax(0,1fr);
3610
+ }
3611
+ .ef-attention-path__primary .ef-cluster > button {
3612
+ inline-size:100%;
3613
+ min-inline-size:0;
3614
+ white-space:normal;
3615
+ block-size:auto;
3616
+ min-block-size:2.75rem;
3617
+ }
3618
+ }
3619
+
3620
+ /* Attention-path extreme text-spacing resilience */
3621
+ .ef-attention-path .ef-status-lozenge {
3622
+ min-inline-size:0;
3623
+ max-inline-size:100%;
3624
+ }
3625
+ @media (max-width:30rem) {
3626
+ .ef-attention-path .ef-status-lozenge {
3627
+ white-space:normal;
3628
+ inline-size:fit-content;
3629
+ }
3630
+ }
3631
+
3632
+
3633
+
3634
+ /* Visual Engineering emphasis-budget composition ----------------------- */
3635
+ .ef-emphasis-budget {
3636
+ display: grid;
3637
+ gap: var(--ef-primitive-spacing-4, 1rem);
3638
+ }
3639
+ .ef-emphasis-budget [data-emphasis] {
3640
+ min-inline-size: 0;
3641
+ overflow-wrap: anywhere;
3642
+ }
3643
+ .ef-emphasis-budget [data-emphasis="primary"] {
3644
+ padding: var(--ef-primitive-spacing-4, 1rem);
3645
+ border: 2px solid var(--ef-color-border-functional, #3a403c);
3646
+ background: var(--ef-color-surface-primary, #f2efe7);
3647
+ }
3648
+ .ef-emphasis-budget [data-emphasis="secondary"] {
3649
+ padding: var(--ef-primitive-spacing-3, 0.75rem);
3650
+ border-inline-start: 0.2rem solid var(--ef-color-border-functional, #3a403c);
3651
+ }
3652
+ .ef-emphasis-budget [data-emphasis="supporting"] {
3653
+ padding-block: var(--ef-primitive-spacing-2, 0.5rem);
3654
+ border-block-start: 1px solid var(--ef-color-border-subtle, #e3e0d7);
3655
+ }
3656
+ .ef-emphasis-label {
3657
+ margin: 0 0 0.3rem;
3658
+ color: var(--ef-color-text-secondary, #686d68);
3659
+ font-family: var(--ef-primitive-font-family-mono, ui-monospace, monospace);
3660
+ font-size: 0.6875rem;
3661
+ font-weight: 700;
3662
+ letter-spacing: 0.04em;
3663
+ text-transform: uppercase;
3664
+ }
3665
+ .ef-emphasis-budget__support {
3666
+ display: grid;
3667
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
3668
+ gap: var(--ef-primitive-spacing-4, 1rem);
3669
+ }
3670
+ @media (forced-colors: active) {
3671
+ .ef-emphasis-budget [data-emphasis="primary"],
3672
+ .ef-emphasis-budget [data-emphasis="secondary"],
3673
+ .ef-emphasis-budget [data-emphasis="supporting"] {
3674
+ border-color: CanvasText;
3675
+ background: Canvas;
3676
+ color: CanvasText;
3677
+ }
3678
+ }
3679
+
3680
+ /* Emphasis-budget extreme text resilience */
3681
+ .ef-emphasis-budget,
3682
+ .ef-emphasis-budget > *,
3683
+ .ef-emphasis-budget__support,
3684
+ .ef-emphasis-budget__support > * {
3685
+ min-inline-size:0;
3686
+ max-inline-size:100%;
3687
+ }
3688
+ .ef-emphasis-budget .ef-status-lozenge {
3689
+ min-inline-size:0;
3690
+ max-inline-size:100%;
3691
+ }
3692
+ @media (max-width:30rem) {
3693
+ .ef-emphasis-budget .ef-status-lozenge {
3694
+ white-space:normal;
3695
+ inline-size:fit-content;
3696
+ }
3697
+ .ef-emphasis-budget [data-emphasis="primary"] > button {
3698
+ min-inline-size:0;
3699
+ max-inline-size:100%;
3700
+ white-space:normal;
3701
+ block-size:auto;
3702
+ min-block-size:2.75rem;
3703
+ }
3704
+ }
3705
+
3706
+ }
3707
+
3708
+
3709
+ @layer echelon.components {
3710
+ /* CharacterGrid ------------------------------------------------------- */
3711
+ /*
3712
+ * A fixed rows x columns grid of equal-width cells. Every run declares its
3713
+ * own (row, col, len[, height]) with data-ef-* attributes; source order is
3714
+ * row-major order, so reading, focus, and visual order agree without
3715
+ * tabindex. See requirements/CHARACTER-GRID.md.
3716
+ */
3717
+ .ef-character-grid {
3718
+ --ef-grid-rows: 24;
3719
+ --ef-grid-columns: 80;
3720
+ --ef-grid-font-size: 1rem;
3721
+ --ef-grid-line-height: 1.25;
3722
+ /* 1.5rem floor: WCAG 2.2 SC 2.5.8 needs 24px targets in adjacent rows. */
3723
+ --ef-grid-row-pitch: max(calc(var(--ef-grid-line-height) * 1em), 1.5rem);
3724
+ --ef-grid-inset: 1ch;
3725
+ --ef-grid-background: var(--ef-color-surface-primary, #f2efe7);
3726
+ --ef-grid-foreground: var(--ef-color-text-primary, #171a18);
3727
+ --ef-grid-protected: var(--ef-color-text-primary, #171a18);
3728
+ --ef-grid-emphasis: var(--ef-color-text-heading, #202421);
3729
+ --ef-grid-muted: var(--ef-color-text-secondary, #686d68);
3730
+ --ef-grid-field: var(--ef-color-text-primary, #171a18);
3731
+ --ef-grid-field-surface: var(--ef-color-surface-secondary, #e3e0d7);
3732
+ --ef-grid-boundary: var(--ef-color-border-functional, #3a403c);
3733
+ --ef-grid-focus: var(--ef-color-focus-ring, #171a18);
3734
+ --ef-grid-information: var(--ef-color-text-primary, #171a18);
3735
+ --ef-grid-success: var(--ef-color-text-primary, #171a18);
3736
+ --ef-grid-warning: var(--ef-color-text-primary, #171a18);
3737
+ --ef-grid-validation: var(--ef-color-text-primary, #171a18);
3738
+ --ef-grid-error: var(--ef-color-text-primary, #171a18);
3739
+ container: ef-character-grid / inline-size;
3740
+ display: block;
3741
+ max-inline-size: 100%;
3742
+ min-inline-size: 0;
3743
+ font-family: var(--ef-primitive-font-family-mono, ui-monospace, monospace);
3744
+ font-size: var(--ef-grid-font-size);
3745
+ }
3746
+
3747
+ .ef-character-grid__viewport {
3748
+ max-inline-size: 100%;
3749
+ overflow-x: auto;
3750
+ overscroll-behavior-inline: contain;
3751
+ background: var(--ef-grid-background);
3752
+ color: var(--ef-grid-foreground);
3753
+ border: 1px solid var(--ef-color-border-functional, #3a403c);
3754
+ }
3755
+
3756
+ .ef-character-grid__viewport:focus-visible {
3757
+ outline: 2px solid var(--ef-color-focus-ring, #171a18);
3758
+ outline-offset: 2px;
3759
+ }
3760
+
3761
+ .ef-character-grid__surface {
3762
+ display: grid;
3763
+ /*
3764
+ * Tracks are one cell at rest but intrinsic above it (GAP-TCG-11): when a
3765
+ * user's text-spacing override widens glyphs past 1ch, the shared column
3766
+ * and row tracks grow, so every row stays aligned and no run overlaps
3767
+ * the next. Without an override every track resolves to exactly 1ch and
3768
+ * one row pitch.
3769
+ */
3770
+ grid-template-columns: repeat(var(--ef-grid-columns), minmax(1ch, min-content));
3771
+ grid-template-rows: repeat(var(--ef-grid-rows), minmax(var(--ef-grid-row-pitch), min-content));
3772
+ inline-size: max-content;
3773
+ margin: 0;
3774
+ padding: var(--ef-grid-inset);
3775
+ font: inherit;
3776
+ line-height: var(--ef-grid-row-pitch);
3777
+ font-variant-ligatures: none;
3778
+ font-kerning: none;
3779
+ font-synthesis: none;
3780
+ color: var(--ef-grid-protected);
3781
+ }
3782
+
3783
+ /*
3784
+ * Device status rows (Visual Engineering DF-VE-TCG-2026-1320, GAP-TCG-12).
3785
+ * data-ef-rows is the application's presentation space; data-ef-status-rows
3786
+ * adds rows after it, in the same tracks so columns stay aligned, for
3787
+ * system status only (CG-18). A screen modeling a terminal whose device
3788
+ * draws a status line outside the application's rows opts in; a screen
3789
+ * whose application draws its own status (DOS, most TUIs) does not.
3790
+ */
3791
+ .ef-character-grid[data-ef-status-rows] .ef-character-grid__surface {
3792
+ grid-template-rows:
3793
+ repeat(var(--ef-grid-rows), minmax(var(--ef-grid-row-pitch), min-content))
3794
+ repeat(var(--ef-grid-status-rows, 1), minmax(var(--ef-grid-row-pitch), min-content));
3795
+ }
3796
+
3797
+ /* Every direct child of the surface or of a group is a positioned run. */
3798
+ :is(.ef-character-grid__surface, .ef-character-grid__group) > * {
3799
+ grid-row: var(--ef-row) / span var(--ef-height);
3800
+ grid-column: var(--ef-col) / span var(--ef-len);
3801
+ /* Exactly the run's cells; the absorbing end margin never widens the box. */
3802
+ inline-size: 100%;
3803
+ min-inline-size: 0;
3804
+ /* Runs ignore foundation target-size minimums; rows set the pitch. */
3805
+ min-block-size: 0;
3806
+ /* Runs ignore foundation measure and color rules for p, h*, label, etc. */
3807
+ max-inline-size: none;
3808
+ color: inherit;
3809
+ overflow-wrap: normal;
3810
+ /*
3811
+ * The negative end margin absorbs glyph-advance rounding (a glyph can
3812
+ * advance a fraction of a pixel more than the computed 1ch, and the error
3813
+ * grows with run length) so rounding never grows an intrinsic track. A
3814
+ * real text-spacing override adds about 0.2ch per cell, twenty times this
3815
+ * allowance, and still does.
3816
+ */
3817
+ margin: 0;
3818
+ margin-inline-end: calc(var(--ef-len) * -0.01ch - 0.5px);
3819
+ padding: 0;
3820
+ border: 0;
3821
+ font: inherit;
3822
+ line-height: inherit;
3823
+ letter-spacing: 0;
3824
+ text-transform: none;
3825
+ white-space: pre;
3826
+ /* Overflow is an authoring error; it stays visible rather than hidden. */
3827
+ overflow: visible;
3828
+ }
3829
+
3830
+ /*
3831
+ * A group is a semantic container (dl, role=group, section, ...) that spans
3832
+ * the whole grid as a subgrid, so its children keep absolute coordinates.
3833
+ */
3834
+ :is(.ef-character-grid__surface, .ef-character-grid__group) > .ef-character-grid__group {
3835
+ grid-row: 1 / -1;
3836
+ grid-column: 1 / -1;
3837
+ display: grid;
3838
+ grid-template-columns: subgrid;
3839
+ grid-template-rows: subgrid;
3840
+ pointer-events: none;
3841
+ }
3842
+
3843
+ .ef-character-grid__group > * {
3844
+ pointer-events: auto;
3845
+ }
3846
+
3847
+ .ef-character-grid__text[data-ef-emphasis="intensified"] {
3848
+ color: var(--ef-grid-emphasis);
3849
+ font-weight: 700;
3850
+ }
3851
+
3852
+ .ef-character-grid__text[data-ef-emphasis="muted"] {
3853
+ color: var(--ef-grid-muted);
3854
+ }
3855
+
3856
+ .ef-character-grid__value {
3857
+ color: var(--ef-grid-emphasis);
3858
+ }
3859
+
3860
+ :is(.ef-character-grid__text, .ef-character-grid__value)[data-ef-align="end"] {
3861
+ text-align: end;
3862
+ }
3863
+
3864
+ .ef-character-grid__value[data-ef-state="missing"] {
3865
+ font-style: italic;
3866
+ }
3867
+
3868
+ /* Positioned repeated rows (a table placed as one run). */
3869
+ /*
3870
+ * Whitespace collapses in a table run: preserved source indentation around
3871
+ * the table would otherwise render as blank lines and push its rows past
3872
+ * the run's declared height. Cells restore white-space: pre below.
3873
+ */
3874
+ :is(.ef-character-grid__surface, .ef-character-grid__group) > .ef-character-grid__table {
3875
+ white-space: normal;
3876
+ }
3877
+
3878
+ /*
3879
+ * Automatic table layout: th[data-ef-len] widths act as minimums, so a
3880
+ * text-spacing override widens a column instead of pushing its text into
3881
+ * the next one (GAP-TCG-11). Without an override every column is exactly
3882
+ * its declared cells.
3883
+ */
3884
+ .ef-character-grid__table > table {
3885
+ border-collapse: separate;
3886
+ border-spacing: 0;
3887
+ table-layout: auto;
3888
+ inline-size: max-content;
3889
+ font: inherit;
3890
+ line-height: inherit;
3891
+ color: inherit;
3892
+ }
3893
+
3894
+ .ef-character-grid__table caption {
3895
+ position: absolute;
3896
+ inline-size: 1px;
3897
+ block-size: 1px;
3898
+ margin: -1px;
3899
+ padding: 0;
3900
+ overflow: hidden;
3901
+ clip-path: inset(50%);
3902
+ white-space: nowrap;
3903
+ }
3904
+
3905
+ .ef-character-grid__table :is(th, td) {
3906
+ block-size: var(--ef-grid-row-pitch);
3907
+ padding: 0;
3908
+ border: 0;
3909
+ font: inherit;
3910
+ line-height: inherit;
3911
+ text-align: start;
3912
+ vertical-align: top;
3913
+ white-space: pre;
3914
+ overflow: visible;
3915
+ }
3916
+
3917
+ .ef-character-grid__table th[data-ef-len] {
3918
+ inline-size: calc(var(--ef-len) * 1ch);
3919
+ }
3920
+
3921
+ .ef-character-grid__table :is(th, td) + :is(th, td) {
3922
+ padding-inline-start: calc(var(--ef-gutter) * 1ch);
3923
+ }
3924
+
3925
+ .ef-character-grid__table th {
3926
+ color: var(--ef-grid-emphasis);
3927
+ text-decoration: underline;
3928
+ text-underline-offset: 0.2em;
3929
+ }
3930
+
3931
+ .ef-character-grid__table td {
3932
+ color: var(--ef-grid-emphasis);
3933
+ }
3934
+
3935
+ /* A row header names its record; it reads as data, not as a column head. */
3936
+ .ef-character-grid__table th[scope="row"] {
3937
+ color: var(--ef-grid-emphasis);
3938
+ text-decoration: none;
3939
+ }
3940
+
3941
+ /*
3942
+ * Per-row selection field (GAP-TCG-10): a native field in a table cell is
3943
+ * exactly data-ef-len cells wide, like a positioned field; its column may
3944
+ * be wider.
3945
+ */
3946
+ .ef-character-grid__table .ef-character-grid__field {
3947
+ display: block;
3948
+ inline-size: calc(var(--ef-len) * 1ch);
3949
+ }
3950
+
3951
+ .ef-character-grid__table [data-ef-align="end"] {
3952
+ text-align: end;
3953
+ }
3954
+
3955
+ .ef-character-grid__table td[colspan] {
3956
+ white-space: normal;
3957
+ }
3958
+
3959
+ /* Protected labels and editable fields (requirements/CHARACTER-GRID.md). */
3960
+ .ef-character-grid__label {
3961
+ color: var(--ef-grid-protected);
3962
+ cursor: default;
3963
+ }
3964
+
3965
+ /* Leader characters (". . . :") are decorative and hidden from the name. */
3966
+ .ef-character-grid__leader {
3967
+ color: var(--ef-grid-muted);
3968
+ }
3969
+
3970
+ .ef-character-grid__field {
3971
+ appearance: none;
3972
+ box-sizing: border-box;
3973
+ inline-size: 100%;
3974
+ block-size: var(--ef-grid-row-pitch);
3975
+ padding: 0;
3976
+ border: 0;
3977
+ border-block-end: 2px solid var(--ef-grid-boundary);
3978
+ border-radius: 0;
3979
+ /* Also outside runs (table cells): the row pitch, not the foundation minimum. */
3980
+ min-block-size: 0;
3981
+ background: var(--ef-grid-field-surface);
3982
+ color: var(--ef-grid-field);
3983
+ caret-color: currentColor;
3984
+ font: inherit;
3985
+ line-height: inherit;
3986
+ letter-spacing: 0;
3987
+ }
3988
+
3989
+ /*
3990
+ * Where supported, a field sizes to its value but never below its declared
3991
+ * cells, so a text-spacing override widens the field (and its shared
3992
+ * column tracks) instead of scrolling part of the value out of view
3993
+ * (GAP-TCG-11). Without support the value scrolls natively in the field.
3994
+ */
3995
+ @supports (field-sizing: content) {
3996
+ .ef-character-grid__field {
3997
+ field-sizing: content;
3998
+ justify-self: start;
3999
+ inline-size: auto;
4000
+ min-inline-size: 100%;
4001
+ }
4002
+
4003
+ .ef-character-grid__table .ef-character-grid__field {
4004
+ inline-size: auto;
4005
+ min-inline-size: calc(var(--ef-len) * 1ch);
4006
+ }
4007
+ }
4008
+
4009
+ .ef-character-grid__field:focus-visible {
4010
+ outline: 2px solid var(--ef-grid-focus);
4011
+ outline-offset: 1px;
4012
+ }
4013
+
4014
+ /* State cues differ in shape, not only color. */
4015
+ .ef-character-grid__field:required {
4016
+ border-block-end-style: double;
4017
+ border-block-end-width: 4px;
4018
+ }
4019
+
4020
+ /*
4021
+ * Dashed rules above and below: a shape cue that adds no inline width, so
4022
+ * an invalid field stays exactly its cells in every state.
4023
+ */
4024
+ .ef-character-grid__field[aria-invalid="true"] {
4025
+ border-block: 2px dashed var(--ef-grid-validation);
4026
+ }
4027
+
4028
+ .ef-character-grid__field:disabled {
4029
+ border-block-end-style: dotted;
4030
+ background: transparent;
4031
+ color: var(--ef-grid-muted);
4032
+ cursor: not-allowed;
4033
+ }
4034
+
4035
+ .ef-character-grid__field:read-only:not(:disabled) {
4036
+ border-block-end-width: 1px;
4037
+ background: transparent;
4038
+ }
4039
+
4040
+ /*
4041
+ * Action keys: native buttons presenting a key name and a label. Forma
4042
+ * presents them; the application/Limen owns what they do.
4043
+ */
4044
+ .ef-character-grid__key {
4045
+ appearance: none;
4046
+ box-sizing: border-box;
4047
+ inline-size: 100%;
4048
+ block-size: var(--ef-grid-row-pitch);
4049
+ padding: 0;
4050
+ border: 0;
4051
+ border-radius: 0;
4052
+ background: transparent;
4053
+ color: var(--ef-grid-protected);
4054
+ font: inherit;
4055
+ line-height: inherit;
4056
+ letter-spacing: 0;
4057
+ text-align: start;
4058
+ white-space: pre;
4059
+ cursor: pointer;
4060
+ }
4061
+
4062
+ .ef-character-grid__key kbd {
4063
+ font: inherit;
4064
+ font-weight: 700;
4065
+ color: var(--ef-grid-emphasis);
4066
+ }
4067
+
4068
+ .ef-character-grid__key:hover {
4069
+ text-decoration: underline;
4070
+ }
4071
+
4072
+ .ef-character-grid__key:focus-visible {
4073
+ outline: 2px solid var(--ef-grid-focus);
4074
+ outline-offset: 1px;
4075
+ }
4076
+
4077
+ .ef-character-grid__key:disabled {
4078
+ color: var(--ef-grid-muted);
4079
+ text-decoration: line-through;
4080
+ cursor: not-allowed;
4081
+ }
4082
+
4083
+ .ef-character-grid__key:disabled kbd {
4084
+ color: inherit;
4085
+ }
4086
+
4087
+ /* Messages and system status: live regions with a visible severity word. */
4088
+ .ef-character-grid__message {
4089
+ white-space: pre-wrap;
4090
+ overflow-wrap: anywhere;
4091
+ color: var(--ef-grid-information);
4092
+ }
4093
+
4094
+ .ef-character-grid__severity {
4095
+ font-weight: 700;
4096
+ }
4097
+
4098
+ .ef-character-grid__message[data-ef-severity="success"] { color: var(--ef-grid-success); }
4099
+ .ef-character-grid__message[data-ef-severity="warning"] { color: var(--ef-grid-warning); }
4100
+ .ef-character-grid__message[data-ef-severity="validation"] { color: var(--ef-grid-validation); }
4101
+ .ef-character-grid__message[data-ef-severity="error"] { color: var(--ef-grid-error); }
4102
+
4103
+ /* Shape cues in addition to the severity word. */
4104
+ .ef-character-grid__message[data-ef-severity="warning"] .ef-character-grid__severity {
4105
+ text-decoration: underline;
4106
+ text-decoration-thickness: 2px;
4107
+ }
4108
+
4109
+ .ef-character-grid__message[data-ef-severity="validation"] .ef-character-grid__severity {
4110
+ text-decoration: underline double;
4111
+ }
4112
+
4113
+ .ef-character-grid__message[data-ef-severity="error"] .ef-character-grid__severity,
4114
+ .ef-character-grid__indicator[data-ef-state="inhibited"] {
4115
+ background: currentColor;
4116
+ outline: 1px solid currentColor;
4117
+ }
4118
+
4119
+ .ef-character-grid__message[data-ef-severity="error"] .ef-character-grid__severity > span,
4120
+ .ef-character-grid__indicator[data-ef-state="inhibited"] > span {
4121
+ color: var(--ef-grid-background);
4122
+ }
4123
+
4124
+ .ef-character-grid__status {
4125
+ color: var(--ef-grid-muted);
4126
+ white-space: pre;
4127
+ }
4128
+
4129
+ .ef-character-grid__indicator {
4130
+ color: var(--ef-grid-emphasis);
4131
+ font-weight: 700;
4132
+ }
4133
+
4134
+ /*
4135
+ * SequentialReveal presentation (Visual Engineering CN-VE-TCG-2026-F9F1).
4136
+ * Visual only: a clip mask over text that is already in the DOM. Static is
4137
+ * the default; data-ef-reveal="sequential" opts a grid in and
4138
+ * data-ef-reveal-run opts a protected text run in. Timing derives from
4139
+ * the run's position, so reveal order is row-major order. Starting,
4140
+ * interrupting (data-ef-reveal="complete"), and replaying are
4141
+ * application/Limen behavior.
4142
+ */
4143
+ .ef-character-grid {
4144
+ --ef-reveal-char-ms: 12;
4145
+ --ef-reveal-line-ms: 40;
4146
+ --ef-reveal-max-ms: 1500;
4147
+ }
4148
+
4149
+ .ef-character-grid[data-ef-reveal="sequential"] {
4150
+ --ef-reveal-row-ms: calc(var(--ef-grid-columns) * var(--ef-reveal-char-ms) + var(--ef-reveal-line-ms));
4151
+ --ef-reveal-total-ms: calc(var(--ef-reveal-rows, var(--ef-grid-rows)) * var(--ef-reveal-row-ms));
4152
+ --ef-reveal-scale: min(1, calc(var(--ef-reveal-max-ms) / var(--ef-reveal-total-ms)));
4153
+ }
4154
+
4155
+ .ef-character-grid[data-ef-reveal="sequential"] :is(.ef-character-grid__surface, .ef-character-grid__group) > .ef-character-grid__text[data-ef-reveal-run] {
4156
+ animation-name: ef-character-grid-reveal;
4157
+ animation-duration: calc(var(--ef-len) * var(--ef-reveal-char-ms) * var(--ef-reveal-scale) * 1ms);
4158
+ animation-delay: calc(((var(--ef-row) - 1) * var(--ef-reveal-row-ms) + (var(--ef-col) - 1) * var(--ef-reveal-char-ms)) * var(--ef-reveal-scale) * 1ms);
4159
+ animation-timing-function: steps(var(--ef-len), jump-start);
4160
+ animation-fill-mode: both;
4161
+ animation-iteration-count: 1;
4162
+ }
4163
+
4164
+ .ef-character-grid[data-ef-reveal="sequential"] :is(.ef-character-grid__surface, .ef-character-grid__group) > .ef-character-grid__text[data-ef-reveal-run]:dir(rtl) {
4165
+ animation-name: ef-character-grid-reveal-rtl;
4166
+ }
4167
+
4168
+ @keyframes ef-character-grid-reveal {
4169
+ from { clip-path: inset(0 100% 0 0); }
4170
+ to { clip-path: inset(0 0 0 0); }
4171
+ }
4172
+
4173
+ @keyframes ef-character-grid-reveal-rtl {
4174
+ from { clip-path: inset(0 0 0 100%); }
4175
+ to { clip-path: inset(0 0 0 0); }
4176
+ }
4177
+
4178
+ /* Reduced motion and print are always static. */
4179
+ @media (prefers-reduced-motion: reduce), print {
4180
+ .ef-character-grid[data-ef-reveal="sequential"] :is(.ef-character-grid__surface, .ef-character-grid__group) > .ef-character-grid__text[data-ef-reveal-run] {
4181
+ animation: none;
4182
+ clip-path: none;
4183
+ }
4184
+ }
4185
+
4186
+ /*
4187
+ * Profiles set presentation tokens only. They never change geometry,
4188
+ * placement, order, or semantics (Visual Engineering boundary rule B-8).
4189
+ *
4190
+ * ibm-3270: first reference profile. Colors evoke the 3279 base palette
4191
+ * (protected blue/white, unprotected green); this is a stylistic choice,
4192
+ * not an emulation.
4193
+ */
4194
+ .ef-character-grid[data-ef-profile="ibm-3270"] {
4195
+ --ef-grid-background: #000000;
4196
+ --ef-grid-foreground: #7aa7ff;
4197
+ --ef-grid-protected: #7aa7ff;
4198
+ --ef-grid-emphasis: #f2f2f2;
4199
+ --ef-grid-muted: #9fb8e8;
4200
+ --ef-grid-field: #5ee08f;
4201
+ --ef-grid-field-surface: #0b1f12;
4202
+ --ef-grid-boundary: #5ee08f;
4203
+ --ef-grid-focus: #4fe3d6;
4204
+ --ef-grid-information: #f2f2f2;
4205
+ --ef-grid-success: #5ee08f;
4206
+ --ef-grid-warning: #ffe066;
4207
+ --ef-grid-validation: #ff9ad5;
4208
+ --ef-grid-error: #ff7a7a;
4209
+ }
4210
+
4211
+ /* A rule over the status row (EV-VE-TCG-2026-1EB5): stylistic, never the only cue. */
4212
+ .ef-character-grid[data-ef-profile="ibm-3270"][data-ef-status-rows] .ef-character-grid__status {
4213
+ box-shadow: 0 -1px 0 0 var(--ef-grid-muted);
4214
+ }
4215
+
4216
+ .ef-character-grid[data-ef-profile="ibm-3270"] .ef-character-grid__viewport {
4217
+ border-color: #3a3a3a;
4218
+ box-shadow: inset 0 0 0 1px #111111;
4219
+ }
4220
+
4221
+ /* The block cursor is a stylistic cue layered on the standard focus outline. */
4222
+ .ef-character-grid[data-ef-profile="ibm-3270"] .ef-character-grid__field {
4223
+ caret-color: var(--ef-grid-focus);
4224
+ caret-shape: block;
4225
+ }
4226
+
4227
+ .ef-character-grid[data-ef-profile="ibm-3270"] .ef-character-grid__field:focus-visible {
4228
+ background: #10301c;
4229
+ }
4230
+
4231
+ .ef-character-grid[data-ef-profile="ibm-3270"] .ef-character-grid__key:focus-visible {
4232
+ background: #10223f;
4233
+ }
4234
+
4235
+ /*
4236
+ * Touch pitch: on narrow or coarse-pointer screens rows grow to a 44px
4237
+ * minimum so fields and keys remain usable targets. Columns stay 1ch.
4238
+ */
4239
+ @media (max-width: 40rem), (pointer: coarse) {
4240
+ .ef-character-grid {
4241
+ --ef-grid-row-pitch: max(calc(var(--ef-grid-line-height) * 1em), 2.75rem);
4242
+ }
4243
+
4244
+ /*
4245
+ * A field shorter than five cells must be followed by blank cells (CG-13).
4246
+ * The negative end margin cancels the extra target width in track sizing,
4247
+ * so a short target paints into those blank cells without widening them.
4248
+ */
4249
+ .ef-character-grid__field,
4250
+ .ef-character-grid__key {
4251
+ min-inline-size: max(100%, 2.75rem);
4252
+ margin-inline-end: min(calc(var(--ef-len) * -0.01ch - 0.5px), calc(var(--ef-len) * 1ch - 2.75rem - 0.5px));
4253
+ }
4254
+
4255
+ /* In a table the touch minimum extends into the gutter (CG-17). */
4256
+ .ef-character-grid__table .ef-character-grid__field {
4257
+ min-inline-size: max(calc(var(--ef-len) * 1ch), 2.75rem);
4258
+ }
4259
+ }
4260
+
4261
+ /*
4262
+ * Reflow is opt-in (data-ef-narrow="reflow") for screens whose positions
4263
+ * carry no meaning. It linearizes runs in source order. The default,
4264
+ * "contained", keeps the grid inside the scrollable viewport.
4265
+ */
4266
+ @container ef-character-grid (inline-size < 82ch) {
4267
+ .ef-character-grid[data-ef-narrow="reflow"] :is(.ef-character-grid__surface, .ef-character-grid__group) {
4268
+ display: flex;
4269
+ flex-direction: column;
4270
+ align-items: start;
4271
+ inline-size: auto;
4272
+ max-inline-size: 100%;
4273
+ pointer-events: auto;
4274
+ }
4275
+
4276
+ .ef-character-grid[data-ef-narrow="reflow"] :is(.ef-character-grid__surface, .ef-character-grid__group) > * {
4277
+ max-inline-size: 100%;
4278
+ min-block-size: var(--ef-grid-row-pitch);
4279
+ white-space: pre-wrap;
4280
+ overflow-wrap: anywhere;
4281
+ }
4282
+
4283
+ .ef-character-grid[data-ef-narrow="reflow"] .ef-character-grid__table {
4284
+ overflow-x: auto;
4285
+ inline-size: 100%;
4286
+ }
4287
+ }
4288
+
4289
+ @media (forced-colors: active) {
4290
+ .ef-character-grid__viewport {
4291
+ border-color: CanvasText;
4292
+ }
4293
+
4294
+ .ef-character-grid__table th {
4295
+ text-decoration-color: CanvasText;
4296
+ }
4297
+
4298
+ .ef-character-grid__field {
4299
+ border-block-end-color: CanvasText;
4300
+ }
4301
+
4302
+ .ef-character-grid__field[aria-invalid="true"] {
4303
+ border-color: CanvasText;
4304
+ }
4305
+
4306
+ .ef-character-grid__field:disabled {
4307
+ border-block-end-color: GrayText;
4308
+ color: GrayText;
4309
+ }
4310
+
4311
+ .ef-character-grid__field:focus-visible,
4312
+ .ef-character-grid__key:focus-visible {
4313
+ outline-color: Highlight;
4314
+ }
4315
+
4316
+ .ef-character-grid__key:disabled {
4317
+ color: GrayText;
4318
+ }
4319
+
4320
+ /* Reverse video is lost in forced colors; keep a visible box instead. */
4321
+ .ef-character-grid__message[data-ef-severity="error"] .ef-character-grid__severity,
4322
+ .ef-character-grid__indicator[data-ef-state="inhibited"] {
4323
+ background: Canvas;
4324
+ outline: 2px solid CanvasText;
4325
+ }
4326
+
4327
+ .ef-character-grid__message[data-ef-severity="error"] .ef-character-grid__severity > span,
4328
+ .ef-character-grid__indicator[data-ef-state="inhibited"] > span {
4329
+ color: CanvasText;
4330
+ }
4331
+ }
4332
+
4333
+ /*
4334
+ * Diagram presentation (requirements/OBJECT-METADATA-AND-DIAGRAM-PRESENTATION.md,
4335
+ * FMD-M1; docs/decisions/ADR-0004-diagram-presentation-boundary.md).
4336
+ * Presentation only. The consumer supplies geometry (--ef-diagram-x, -y, -w
4337
+ * in canvas px, and SVG path data), semantics, and any metadata-to-appearance
4338
+ * mapping. Authored appearance inputs, each falling back to a Forma token
4339
+ * when removed:
4340
+ * node: --ef-diagram-fill, --ef-diagram-stroke, --ef-diagram-accent,
4341
+ * --ef-diagram-foreground
4342
+ * connector: --ef-diagram-connector-stroke, --ef-diagram-connector-width
4343
+ * Non-color cues: the visible node kind text, data-ef-shape, data-ef-line and
4344
+ * the textual relationship list. Focus never reads authored color.
4345
+ */
4346
+ .ef-diagram { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--ef-primitive-spacing-4, 1rem); min-inline-size: 0; margin: 0; }
4347
+ .ef-diagram > figcaption { font-weight: 700; }
4348
+ .ef-diagram__viewport {
4349
+ max-inline-size: 100%;
4350
+ overflow: auto;
4351
+ overscroll-behavior: contain;
4352
+ border: 1px solid var(--ef-color-border-subtle, #e3e0d7);
4353
+ background: var(--ef-color-surface-primary, #f2efe7);
4354
+ }
4355
+ .ef-diagram__canvas {
4356
+ position: relative;
4357
+ inline-size: var(--ef-diagram-canvas-w, 720px);
4358
+ block-size: var(--ef-diagram-canvas-h, 320px);
4359
+ margin: 0;
4360
+ padding: 0;
4361
+ list-style: none;
4362
+ }
4363
+ /* Canvas coordinates are physical, like SVG: they do not mirror in RTL. */
4364
+ .ef-diagram__wires { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; overflow: visible; pointer-events: none; }
4365
+
4366
+ .ef-diagram-node {
4367
+ --ef-diagram-node-fill: var(--ef-diagram-fill, var(--ef-color-surface-primary, #f2efe7));
4368
+ --ef-diagram-node-stroke: var(--ef-diagram-stroke, var(--ef-color-border-functional, #3a403c));
4369
+ --ef-diagram-node-accent: var(--ef-diagram-accent, var(--ef-diagram-node-stroke));
4370
+ --ef-diagram-node-foreground: var(--ef-diagram-foreground, var(--ef-color-text-primary, #171a18));
4371
+ position: absolute;
4372
+ left: var(--ef-diagram-x, 0);
4373
+ top: var(--ef-diagram-y, 0);
4374
+ inline-size: var(--ef-diagram-w, 12rem);
4375
+ display: grid;
4376
+ gap: var(--ef-primitive-spacing-1, 0.25rem);
4377
+ padding: var(--ef-primitive-spacing-3, 0.75rem);
4378
+ border: 2px solid var(--ef-diagram-node-stroke);
4379
+ border-inline-start: 6px solid var(--ef-diagram-node-accent);
4380
+ border-radius: 0;
4381
+ background: var(--ef-diagram-node-fill);
4382
+ color: var(--ef-diagram-node-foreground);
4383
+ overflow-wrap: anywhere;
4384
+ }
4385
+ .ef-diagram-node[data-ef-shape="rounded"] { border-radius: var(--ef-primitive-spacing-3, 0.75rem); }
4386
+ .ef-diagram-node[data-ef-shape="pill"] { border-radius: 999px; padding-inline: var(--ef-primitive-spacing-5, 1.5rem); }
4387
+ .ef-diagram-node :where(h3, p, dl, dd) { margin: 0; color: inherit; max-inline-size: none; }
4388
+ .ef-diagram-node__label { font-size: 1rem; line-height: 1.25; }
4389
+ .ef-diagram-node a { color: inherit; }
4390
+ .ef-diagram-node__kind { font-size: 0.8125rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
4391
+ .ef-diagram-node__meta { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0 var(--ef-primitive-spacing-2, 0.5rem); font-size: 0.875rem; }
4392
+ .ef-diagram-node__meta dt { font-weight: 700; }
4393
+
4394
+ .ef-diagram-connector {
4395
+ fill: none;
4396
+ stroke: var(--ef-diagram-connector-stroke, var(--ef-color-border-functional, #3a403c));
4397
+ stroke-width: var(--ef-diagram-connector-width, 2);
4398
+ }
4399
+ .ef-diagram-connector[data-ef-line="dashed"] { stroke-dasharray: 8 6; }
4400
+ .ef-diagram-connector[data-ef-line="dotted"] { stroke-dasharray: 2 5; stroke-linecap: round; }
4401
+ .ef-diagram-marker { fill: var(--ef-color-border-functional, #3a403c); stroke: none; }
4402
+ .ef-diagram-connector__label {
4403
+ position: absolute;
4404
+ left: var(--ef-diagram-x, 0);
4405
+ top: var(--ef-diagram-y, 0);
4406
+ padding: 0 var(--ef-primitive-spacing-1, 0.25rem);
4407
+ background: var(--ef-color-surface-primary, #f2efe7);
4408
+ color: var(--ef-color-text-primary, #171a18);
4409
+ font-size: 0.875rem;
4410
+ white-space: nowrap;
4411
+ }
4412
+
4413
+ /* The text equivalent: every relationship in reading order. */
4414
+ .ef-diagram__relations { margin: 0; padding-inline-start: 1.25rem; }
4415
+ .ef-diagram__relations :where(li) { color: var(--ef-color-text-primary, #171a18); }
4416
+
4417
+ .ef-diagram-legend { display: flex; flex-wrap: wrap; gap: var(--ef-primitive-spacing-2, 0.5rem) var(--ef-primitive-spacing-5, 1.5rem); margin: 0; }
4418
+ .ef-diagram-legend > div { display: flex; align-items: center; gap: var(--ef-primitive-spacing-2, 0.5rem); }
4419
+ .ef-diagram-legend :where(dt, dd) { margin: 0; min-inline-size: 0; overflow-wrap: anywhere; }
4420
+ .ef-diagram-legend__swatch {
4421
+ display: inline-block;
4422
+ inline-size: 1.25rem;
4423
+ block-size: 1.25rem;
4424
+ border: 2px solid var(--ef-diagram-stroke, var(--ef-color-border-functional, #3a403c));
4425
+ border-inline-start-width: 6px;
4426
+ border-inline-start-color: var(--ef-diagram-accent, var(--ef-diagram-stroke, var(--ef-color-border-functional, #3a403c)));
4427
+ background: var(--ef-diagram-fill, var(--ef-color-surface-primary, #f2efe7));
4428
+ vertical-align: middle;
4429
+ }
4430
+
4431
+ @media (forced-colors: active) {
4432
+ .ef-diagram-node, .ef-diagram-legend__swatch { border-color: CanvasText; background: Canvas; color: CanvasText; }
4433
+ .ef-diagram-connector { stroke: CanvasText; }
4434
+ .ef-diagram-marker { fill: CanvasText; }
4435
+ .ef-diagram-connector__label { background: Canvas; color: CanvasText; }
4436
+ }
4437
+
4438
+ /* Backgrounds-off and grayscale print: boundaries, kinds and line styles remain. */
4439
+ @media print {
4440
+ .ef-diagram__viewport { overflow: visible; border-color: #000; }
4441
+ .ef-diagram-node { break-inside: avoid; border-color: #000; }
4442
+ .ef-diagram { break-inside: avoid; }
4443
+ }
4444
+
4445
+ /* BEGIN generated: character-grid coordinates (tools/character-grid-css.mjs) */
4446
+ .ef-character-grid[data-ef-rows="1"] { --ef-grid-rows: 1; }
4447
+ .ef-character-grid[data-ef-rows="2"] { --ef-grid-rows: 2; }
4448
+ .ef-character-grid[data-ef-rows="3"] { --ef-grid-rows: 3; }
4449
+ .ef-character-grid[data-ef-rows="4"] { --ef-grid-rows: 4; }
4450
+ .ef-character-grid[data-ef-rows="5"] { --ef-grid-rows: 5; }
4451
+ .ef-character-grid[data-ef-rows="6"] { --ef-grid-rows: 6; }
4452
+ .ef-character-grid[data-ef-rows="7"] { --ef-grid-rows: 7; }
4453
+ .ef-character-grid[data-ef-rows="8"] { --ef-grid-rows: 8; }
4454
+ .ef-character-grid[data-ef-rows="9"] { --ef-grid-rows: 9; }
4455
+ .ef-character-grid[data-ef-rows="10"] { --ef-grid-rows: 10; }
4456
+ .ef-character-grid[data-ef-rows="11"] { --ef-grid-rows: 11; }
4457
+ .ef-character-grid[data-ef-rows="12"] { --ef-grid-rows: 12; }
4458
+ .ef-character-grid[data-ef-rows="13"] { --ef-grid-rows: 13; }
4459
+ .ef-character-grid[data-ef-rows="14"] { --ef-grid-rows: 14; }
4460
+ .ef-character-grid[data-ef-rows="15"] { --ef-grid-rows: 15; }
4461
+ .ef-character-grid[data-ef-rows="16"] { --ef-grid-rows: 16; }
4462
+ .ef-character-grid[data-ef-rows="17"] { --ef-grid-rows: 17; }
4463
+ .ef-character-grid[data-ef-rows="18"] { --ef-grid-rows: 18; }
4464
+ .ef-character-grid[data-ef-rows="19"] { --ef-grid-rows: 19; }
4465
+ .ef-character-grid[data-ef-rows="20"] { --ef-grid-rows: 20; }
4466
+ .ef-character-grid[data-ef-rows="21"] { --ef-grid-rows: 21; }
4467
+ .ef-character-grid[data-ef-rows="22"] { --ef-grid-rows: 22; }
4468
+ .ef-character-grid[data-ef-rows="23"] { --ef-grid-rows: 23; }
4469
+ .ef-character-grid[data-ef-rows="24"] { --ef-grid-rows: 24; }
4470
+ .ef-character-grid[data-ef-rows="25"] { --ef-grid-rows: 25; }
4471
+ .ef-character-grid[data-ef-rows="26"] { --ef-grid-rows: 26; }
4472
+ .ef-character-grid[data-ef-rows="27"] { --ef-grid-rows: 27; }
4473
+ .ef-character-grid[data-ef-rows="28"] { --ef-grid-rows: 28; }
4474
+ .ef-character-grid[data-ef-rows="29"] { --ef-grid-rows: 29; }
4475
+ .ef-character-grid[data-ef-rows="30"] { --ef-grid-rows: 30; }
4476
+ .ef-character-grid[data-ef-rows="31"] { --ef-grid-rows: 31; }
4477
+ .ef-character-grid[data-ef-rows="32"] { --ef-grid-rows: 32; }
4478
+ .ef-character-grid[data-ef-rows="33"] { --ef-grid-rows: 33; }
4479
+ .ef-character-grid[data-ef-rows="34"] { --ef-grid-rows: 34; }
4480
+ .ef-character-grid[data-ef-rows="35"] { --ef-grid-rows: 35; }
4481
+ .ef-character-grid[data-ef-rows="36"] { --ef-grid-rows: 36; }
4482
+ .ef-character-grid[data-ef-rows="37"] { --ef-grid-rows: 37; }
4483
+ .ef-character-grid[data-ef-rows="38"] { --ef-grid-rows: 38; }
4484
+ .ef-character-grid[data-ef-rows="39"] { --ef-grid-rows: 39; }
4485
+ .ef-character-grid[data-ef-rows="40"] { --ef-grid-rows: 40; }
4486
+ .ef-character-grid[data-ef-rows="41"] { --ef-grid-rows: 41; }
4487
+ .ef-character-grid[data-ef-rows="42"] { --ef-grid-rows: 42; }
4488
+ .ef-character-grid[data-ef-rows="43"] { --ef-grid-rows: 43; }
4489
+ .ef-character-grid[data-ef-rows="44"] { --ef-grid-rows: 44; }
4490
+ .ef-character-grid[data-ef-rows="45"] { --ef-grid-rows: 45; }
4491
+ .ef-character-grid[data-ef-rows="46"] { --ef-grid-rows: 46; }
4492
+ .ef-character-grid[data-ef-rows="47"] { --ef-grid-rows: 47; }
4493
+ .ef-character-grid[data-ef-rows="48"] { --ef-grid-rows: 48; }
4494
+ .ef-character-grid[data-ef-rows="49"] { --ef-grid-rows: 49; }
4495
+ .ef-character-grid[data-ef-rows="50"] { --ef-grid-rows: 50; }
4496
+ .ef-character-grid[data-ef-columns="1"] { --ef-grid-columns: 1; }
4497
+ .ef-character-grid[data-ef-columns="2"] { --ef-grid-columns: 2; }
4498
+ .ef-character-grid[data-ef-columns="3"] { --ef-grid-columns: 3; }
4499
+ .ef-character-grid[data-ef-columns="4"] { --ef-grid-columns: 4; }
4500
+ .ef-character-grid[data-ef-columns="5"] { --ef-grid-columns: 5; }
4501
+ .ef-character-grid[data-ef-columns="6"] { --ef-grid-columns: 6; }
4502
+ .ef-character-grid[data-ef-columns="7"] { --ef-grid-columns: 7; }
4503
+ .ef-character-grid[data-ef-columns="8"] { --ef-grid-columns: 8; }
4504
+ .ef-character-grid[data-ef-columns="9"] { --ef-grid-columns: 9; }
4505
+ .ef-character-grid[data-ef-columns="10"] { --ef-grid-columns: 10; }
4506
+ .ef-character-grid[data-ef-columns="11"] { --ef-grid-columns: 11; }
4507
+ .ef-character-grid[data-ef-columns="12"] { --ef-grid-columns: 12; }
4508
+ .ef-character-grid[data-ef-columns="13"] { --ef-grid-columns: 13; }
4509
+ .ef-character-grid[data-ef-columns="14"] { --ef-grid-columns: 14; }
4510
+ .ef-character-grid[data-ef-columns="15"] { --ef-grid-columns: 15; }
4511
+ .ef-character-grid[data-ef-columns="16"] { --ef-grid-columns: 16; }
4512
+ .ef-character-grid[data-ef-columns="17"] { --ef-grid-columns: 17; }
4513
+ .ef-character-grid[data-ef-columns="18"] { --ef-grid-columns: 18; }
4514
+ .ef-character-grid[data-ef-columns="19"] { --ef-grid-columns: 19; }
4515
+ .ef-character-grid[data-ef-columns="20"] { --ef-grid-columns: 20; }
4516
+ .ef-character-grid[data-ef-columns="21"] { --ef-grid-columns: 21; }
4517
+ .ef-character-grid[data-ef-columns="22"] { --ef-grid-columns: 22; }
4518
+ .ef-character-grid[data-ef-columns="23"] { --ef-grid-columns: 23; }
4519
+ .ef-character-grid[data-ef-columns="24"] { --ef-grid-columns: 24; }
4520
+ .ef-character-grid[data-ef-columns="25"] { --ef-grid-columns: 25; }
4521
+ .ef-character-grid[data-ef-columns="26"] { --ef-grid-columns: 26; }
4522
+ .ef-character-grid[data-ef-columns="27"] { --ef-grid-columns: 27; }
4523
+ .ef-character-grid[data-ef-columns="28"] { --ef-grid-columns: 28; }
4524
+ .ef-character-grid[data-ef-columns="29"] { --ef-grid-columns: 29; }
4525
+ .ef-character-grid[data-ef-columns="30"] { --ef-grid-columns: 30; }
4526
+ .ef-character-grid[data-ef-columns="31"] { --ef-grid-columns: 31; }
4527
+ .ef-character-grid[data-ef-columns="32"] { --ef-grid-columns: 32; }
4528
+ .ef-character-grid[data-ef-columns="33"] { --ef-grid-columns: 33; }
4529
+ .ef-character-grid[data-ef-columns="34"] { --ef-grid-columns: 34; }
4530
+ .ef-character-grid[data-ef-columns="35"] { --ef-grid-columns: 35; }
4531
+ .ef-character-grid[data-ef-columns="36"] { --ef-grid-columns: 36; }
4532
+ .ef-character-grid[data-ef-columns="37"] { --ef-grid-columns: 37; }
4533
+ .ef-character-grid[data-ef-columns="38"] { --ef-grid-columns: 38; }
4534
+ .ef-character-grid[data-ef-columns="39"] { --ef-grid-columns: 39; }
4535
+ .ef-character-grid[data-ef-columns="40"] { --ef-grid-columns: 40; }
4536
+ .ef-character-grid[data-ef-columns="41"] { --ef-grid-columns: 41; }
4537
+ .ef-character-grid[data-ef-columns="42"] { --ef-grid-columns: 42; }
4538
+ .ef-character-grid[data-ef-columns="43"] { --ef-grid-columns: 43; }
4539
+ .ef-character-grid[data-ef-columns="44"] { --ef-grid-columns: 44; }
4540
+ .ef-character-grid[data-ef-columns="45"] { --ef-grid-columns: 45; }
4541
+ .ef-character-grid[data-ef-columns="46"] { --ef-grid-columns: 46; }
4542
+ .ef-character-grid[data-ef-columns="47"] { --ef-grid-columns: 47; }
4543
+ .ef-character-grid[data-ef-columns="48"] { --ef-grid-columns: 48; }
4544
+ .ef-character-grid[data-ef-columns="49"] { --ef-grid-columns: 49; }
4545
+ .ef-character-grid[data-ef-columns="50"] { --ef-grid-columns: 50; }
4546
+ .ef-character-grid[data-ef-columns="51"] { --ef-grid-columns: 51; }
4547
+ .ef-character-grid[data-ef-columns="52"] { --ef-grid-columns: 52; }
4548
+ .ef-character-grid[data-ef-columns="53"] { --ef-grid-columns: 53; }
4549
+ .ef-character-grid[data-ef-columns="54"] { --ef-grid-columns: 54; }
4550
+ .ef-character-grid[data-ef-columns="55"] { --ef-grid-columns: 55; }
4551
+ .ef-character-grid[data-ef-columns="56"] { --ef-grid-columns: 56; }
4552
+ .ef-character-grid[data-ef-columns="57"] { --ef-grid-columns: 57; }
4553
+ .ef-character-grid[data-ef-columns="58"] { --ef-grid-columns: 58; }
4554
+ .ef-character-grid[data-ef-columns="59"] { --ef-grid-columns: 59; }
4555
+ .ef-character-grid[data-ef-columns="60"] { --ef-grid-columns: 60; }
4556
+ .ef-character-grid[data-ef-columns="61"] { --ef-grid-columns: 61; }
4557
+ .ef-character-grid[data-ef-columns="62"] { --ef-grid-columns: 62; }
4558
+ .ef-character-grid[data-ef-columns="63"] { --ef-grid-columns: 63; }
4559
+ .ef-character-grid[data-ef-columns="64"] { --ef-grid-columns: 64; }
4560
+ .ef-character-grid[data-ef-columns="65"] { --ef-grid-columns: 65; }
4561
+ .ef-character-grid[data-ef-columns="66"] { --ef-grid-columns: 66; }
4562
+ .ef-character-grid[data-ef-columns="67"] { --ef-grid-columns: 67; }
4563
+ .ef-character-grid[data-ef-columns="68"] { --ef-grid-columns: 68; }
4564
+ .ef-character-grid[data-ef-columns="69"] { --ef-grid-columns: 69; }
4565
+ .ef-character-grid[data-ef-columns="70"] { --ef-grid-columns: 70; }
4566
+ .ef-character-grid[data-ef-columns="71"] { --ef-grid-columns: 71; }
4567
+ .ef-character-grid[data-ef-columns="72"] { --ef-grid-columns: 72; }
4568
+ .ef-character-grid[data-ef-columns="73"] { --ef-grid-columns: 73; }
4569
+ .ef-character-grid[data-ef-columns="74"] { --ef-grid-columns: 74; }
4570
+ .ef-character-grid[data-ef-columns="75"] { --ef-grid-columns: 75; }
4571
+ .ef-character-grid[data-ef-columns="76"] { --ef-grid-columns: 76; }
4572
+ .ef-character-grid[data-ef-columns="77"] { --ef-grid-columns: 77; }
4573
+ .ef-character-grid[data-ef-columns="78"] { --ef-grid-columns: 78; }
4574
+ .ef-character-grid[data-ef-columns="79"] { --ef-grid-columns: 79; }
4575
+ .ef-character-grid[data-ef-columns="80"] { --ef-grid-columns: 80; }
4576
+ .ef-character-grid[data-ef-columns="81"] { --ef-grid-columns: 81; }
4577
+ .ef-character-grid[data-ef-columns="82"] { --ef-grid-columns: 82; }
4578
+ .ef-character-grid[data-ef-columns="83"] { --ef-grid-columns: 83; }
4579
+ .ef-character-grid[data-ef-columns="84"] { --ef-grid-columns: 84; }
4580
+ .ef-character-grid[data-ef-columns="85"] { --ef-grid-columns: 85; }
4581
+ .ef-character-grid[data-ef-columns="86"] { --ef-grid-columns: 86; }
4582
+ .ef-character-grid[data-ef-columns="87"] { --ef-grid-columns: 87; }
4583
+ .ef-character-grid[data-ef-columns="88"] { --ef-grid-columns: 88; }
4584
+ .ef-character-grid[data-ef-columns="89"] { --ef-grid-columns: 89; }
4585
+ .ef-character-grid[data-ef-columns="90"] { --ef-grid-columns: 90; }
4586
+ .ef-character-grid[data-ef-columns="91"] { --ef-grid-columns: 91; }
4587
+ .ef-character-grid[data-ef-columns="92"] { --ef-grid-columns: 92; }
4588
+ .ef-character-grid[data-ef-columns="93"] { --ef-grid-columns: 93; }
4589
+ .ef-character-grid[data-ef-columns="94"] { --ef-grid-columns: 94; }
4590
+ .ef-character-grid[data-ef-columns="95"] { --ef-grid-columns: 95; }
4591
+ .ef-character-grid[data-ef-columns="96"] { --ef-grid-columns: 96; }
4592
+ .ef-character-grid[data-ef-columns="97"] { --ef-grid-columns: 97; }
4593
+ .ef-character-grid[data-ef-columns="98"] { --ef-grid-columns: 98; }
4594
+ .ef-character-grid[data-ef-columns="99"] { --ef-grid-columns: 99; }
4595
+ .ef-character-grid[data-ef-columns="100"] { --ef-grid-columns: 100; }
4596
+ .ef-character-grid[data-ef-columns="101"] { --ef-grid-columns: 101; }
4597
+ .ef-character-grid[data-ef-columns="102"] { --ef-grid-columns: 102; }
4598
+ .ef-character-grid[data-ef-columns="103"] { --ef-grid-columns: 103; }
4599
+ .ef-character-grid[data-ef-columns="104"] { --ef-grid-columns: 104; }
4600
+ .ef-character-grid[data-ef-columns="105"] { --ef-grid-columns: 105; }
4601
+ .ef-character-grid[data-ef-columns="106"] { --ef-grid-columns: 106; }
4602
+ .ef-character-grid[data-ef-columns="107"] { --ef-grid-columns: 107; }
4603
+ .ef-character-grid[data-ef-columns="108"] { --ef-grid-columns: 108; }
4604
+ .ef-character-grid[data-ef-columns="109"] { --ef-grid-columns: 109; }
4605
+ .ef-character-grid[data-ef-columns="110"] { --ef-grid-columns: 110; }
4606
+ .ef-character-grid[data-ef-columns="111"] { --ef-grid-columns: 111; }
4607
+ .ef-character-grid[data-ef-columns="112"] { --ef-grid-columns: 112; }
4608
+ .ef-character-grid[data-ef-columns="113"] { --ef-grid-columns: 113; }
4609
+ .ef-character-grid[data-ef-columns="114"] { --ef-grid-columns: 114; }
4610
+ .ef-character-grid[data-ef-columns="115"] { --ef-grid-columns: 115; }
4611
+ .ef-character-grid[data-ef-columns="116"] { --ef-grid-columns: 116; }
4612
+ .ef-character-grid[data-ef-columns="117"] { --ef-grid-columns: 117; }
4613
+ .ef-character-grid[data-ef-columns="118"] { --ef-grid-columns: 118; }
4614
+ .ef-character-grid[data-ef-columns="119"] { --ef-grid-columns: 119; }
4615
+ .ef-character-grid[data-ef-columns="120"] { --ef-grid-columns: 120; }
4616
+ .ef-character-grid[data-ef-columns="121"] { --ef-grid-columns: 121; }
4617
+ .ef-character-grid[data-ef-columns="122"] { --ef-grid-columns: 122; }
4618
+ .ef-character-grid[data-ef-columns="123"] { --ef-grid-columns: 123; }
4619
+ .ef-character-grid[data-ef-columns="124"] { --ef-grid-columns: 124; }
4620
+ .ef-character-grid[data-ef-columns="125"] { --ef-grid-columns: 125; }
4621
+ .ef-character-grid[data-ef-columns="126"] { --ef-grid-columns: 126; }
4622
+ .ef-character-grid[data-ef-columns="127"] { --ef-grid-columns: 127; }
4623
+ .ef-character-grid[data-ef-columns="128"] { --ef-grid-columns: 128; }
4624
+ .ef-character-grid[data-ef-columns="129"] { --ef-grid-columns: 129; }
4625
+ .ef-character-grid[data-ef-columns="130"] { --ef-grid-columns: 130; }
4626
+ .ef-character-grid[data-ef-columns="131"] { --ef-grid-columns: 131; }
4627
+ .ef-character-grid[data-ef-columns="132"] { --ef-grid-columns: 132; }
4628
+ .ef-character-grid[data-ef-status-rows="1"] { --ef-grid-status-rows: 1; }
4629
+ .ef-character-grid[data-ef-status-rows="2"] { --ef-grid-status-rows: 2; }
4630
+ .ef-character-grid[data-ef-reveal-rows="1"] { --ef-reveal-rows: 1; }
4631
+ .ef-character-grid[data-ef-reveal-rows="2"] { --ef-reveal-rows: 2; }
4632
+ .ef-character-grid[data-ef-reveal-rows="3"] { --ef-reveal-rows: 3; }
4633
+ .ef-character-grid[data-ef-reveal-rows="4"] { --ef-reveal-rows: 4; }
4634
+ .ef-character-grid[data-ef-reveal-rows="5"] { --ef-reveal-rows: 5; }
4635
+ .ef-character-grid[data-ef-reveal-rows="6"] { --ef-reveal-rows: 6; }
4636
+ .ef-character-grid[data-ef-reveal-rows="7"] { --ef-reveal-rows: 7; }
4637
+ .ef-character-grid[data-ef-reveal-rows="8"] { --ef-reveal-rows: 8; }
4638
+ .ef-character-grid[data-ef-reveal-rows="9"] { --ef-reveal-rows: 9; }
4639
+ .ef-character-grid[data-ef-reveal-rows="10"] { --ef-reveal-rows: 10; }
4640
+ .ef-character-grid[data-ef-reveal-rows="11"] { --ef-reveal-rows: 11; }
4641
+ .ef-character-grid[data-ef-reveal-rows="12"] { --ef-reveal-rows: 12; }
4642
+ .ef-character-grid[data-ef-reveal-rows="13"] { --ef-reveal-rows: 13; }
4643
+ .ef-character-grid[data-ef-reveal-rows="14"] { --ef-reveal-rows: 14; }
4644
+ .ef-character-grid[data-ef-reveal-rows="15"] { --ef-reveal-rows: 15; }
4645
+ .ef-character-grid[data-ef-reveal-rows="16"] { --ef-reveal-rows: 16; }
4646
+ .ef-character-grid[data-ef-reveal-rows="17"] { --ef-reveal-rows: 17; }
4647
+ .ef-character-grid[data-ef-reveal-rows="18"] { --ef-reveal-rows: 18; }
4648
+ .ef-character-grid[data-ef-reveal-rows="19"] { --ef-reveal-rows: 19; }
4649
+ .ef-character-grid[data-ef-reveal-rows="20"] { --ef-reveal-rows: 20; }
4650
+ .ef-character-grid[data-ef-reveal-rows="21"] { --ef-reveal-rows: 21; }
4651
+ .ef-character-grid[data-ef-reveal-rows="22"] { --ef-reveal-rows: 22; }
4652
+ .ef-character-grid[data-ef-reveal-rows="23"] { --ef-reveal-rows: 23; }
4653
+ .ef-character-grid[data-ef-reveal-rows="24"] { --ef-reveal-rows: 24; }
4654
+ .ef-character-grid[data-ef-reveal-rows="25"] { --ef-reveal-rows: 25; }
4655
+ .ef-character-grid[data-ef-reveal-rows="26"] { --ef-reveal-rows: 26; }
4656
+ .ef-character-grid[data-ef-reveal-rows="27"] { --ef-reveal-rows: 27; }
4657
+ .ef-character-grid[data-ef-reveal-rows="28"] { --ef-reveal-rows: 28; }
4658
+ .ef-character-grid[data-ef-reveal-rows="29"] { --ef-reveal-rows: 29; }
4659
+ .ef-character-grid[data-ef-reveal-rows="30"] { --ef-reveal-rows: 30; }
4660
+ .ef-character-grid[data-ef-reveal-rows="31"] { --ef-reveal-rows: 31; }
4661
+ .ef-character-grid[data-ef-reveal-rows="32"] { --ef-reveal-rows: 32; }
4662
+ .ef-character-grid[data-ef-reveal-rows="33"] { --ef-reveal-rows: 33; }
4663
+ .ef-character-grid[data-ef-reveal-rows="34"] { --ef-reveal-rows: 34; }
4664
+ .ef-character-grid[data-ef-reveal-rows="35"] { --ef-reveal-rows: 35; }
4665
+ .ef-character-grid[data-ef-reveal-rows="36"] { --ef-reveal-rows: 36; }
4666
+ .ef-character-grid[data-ef-reveal-rows="37"] { --ef-reveal-rows: 37; }
4667
+ .ef-character-grid[data-ef-reveal-rows="38"] { --ef-reveal-rows: 38; }
4668
+ .ef-character-grid[data-ef-reveal-rows="39"] { --ef-reveal-rows: 39; }
4669
+ .ef-character-grid[data-ef-reveal-rows="40"] { --ef-reveal-rows: 40; }
4670
+ .ef-character-grid[data-ef-reveal-rows="41"] { --ef-reveal-rows: 41; }
4671
+ .ef-character-grid[data-ef-reveal-rows="42"] { --ef-reveal-rows: 42; }
4672
+ .ef-character-grid[data-ef-reveal-rows="43"] { --ef-reveal-rows: 43; }
4673
+ .ef-character-grid[data-ef-reveal-rows="44"] { --ef-reveal-rows: 44; }
4674
+ .ef-character-grid[data-ef-reveal-rows="45"] { --ef-reveal-rows: 45; }
4675
+ .ef-character-grid[data-ef-reveal-rows="46"] { --ef-reveal-rows: 46; }
4676
+ .ef-character-grid[data-ef-reveal-rows="47"] { --ef-reveal-rows: 47; }
4677
+ .ef-character-grid[data-ef-reveal-rows="48"] { --ef-reveal-rows: 48; }
4678
+ .ef-character-grid[data-ef-reveal-rows="49"] { --ef-reveal-rows: 49; }
4679
+ .ef-character-grid[data-ef-reveal-rows="50"] { --ef-reveal-rows: 50; }
4680
+ :where(.ef-character-grid) [data-ef-row="1"] { --ef-row: 1; }
4681
+ :where(.ef-character-grid) [data-ef-row="2"] { --ef-row: 2; }
4682
+ :where(.ef-character-grid) [data-ef-row="3"] { --ef-row: 3; }
4683
+ :where(.ef-character-grid) [data-ef-row="4"] { --ef-row: 4; }
4684
+ :where(.ef-character-grid) [data-ef-row="5"] { --ef-row: 5; }
4685
+ :where(.ef-character-grid) [data-ef-row="6"] { --ef-row: 6; }
4686
+ :where(.ef-character-grid) [data-ef-row="7"] { --ef-row: 7; }
4687
+ :where(.ef-character-grid) [data-ef-row="8"] { --ef-row: 8; }
4688
+ :where(.ef-character-grid) [data-ef-row="9"] { --ef-row: 9; }
4689
+ :where(.ef-character-grid) [data-ef-row="10"] { --ef-row: 10; }
4690
+ :where(.ef-character-grid) [data-ef-row="11"] { --ef-row: 11; }
4691
+ :where(.ef-character-grid) [data-ef-row="12"] { --ef-row: 12; }
4692
+ :where(.ef-character-grid) [data-ef-row="13"] { --ef-row: 13; }
4693
+ :where(.ef-character-grid) [data-ef-row="14"] { --ef-row: 14; }
4694
+ :where(.ef-character-grid) [data-ef-row="15"] { --ef-row: 15; }
4695
+ :where(.ef-character-grid) [data-ef-row="16"] { --ef-row: 16; }
4696
+ :where(.ef-character-grid) [data-ef-row="17"] { --ef-row: 17; }
4697
+ :where(.ef-character-grid) [data-ef-row="18"] { --ef-row: 18; }
4698
+ :where(.ef-character-grid) [data-ef-row="19"] { --ef-row: 19; }
4699
+ :where(.ef-character-grid) [data-ef-row="20"] { --ef-row: 20; }
4700
+ :where(.ef-character-grid) [data-ef-row="21"] { --ef-row: 21; }
4701
+ :where(.ef-character-grid) [data-ef-row="22"] { --ef-row: 22; }
4702
+ :where(.ef-character-grid) [data-ef-row="23"] { --ef-row: 23; }
4703
+ :where(.ef-character-grid) [data-ef-row="24"] { --ef-row: 24; }
4704
+ :where(.ef-character-grid) [data-ef-row="25"] { --ef-row: 25; }
4705
+ :where(.ef-character-grid) [data-ef-row="26"] { --ef-row: 26; }
4706
+ :where(.ef-character-grid) [data-ef-row="27"] { --ef-row: 27; }
4707
+ :where(.ef-character-grid) [data-ef-row="28"] { --ef-row: 28; }
4708
+ :where(.ef-character-grid) [data-ef-row="29"] { --ef-row: 29; }
4709
+ :where(.ef-character-grid) [data-ef-row="30"] { --ef-row: 30; }
4710
+ :where(.ef-character-grid) [data-ef-row="31"] { --ef-row: 31; }
4711
+ :where(.ef-character-grid) [data-ef-row="32"] { --ef-row: 32; }
4712
+ :where(.ef-character-grid) [data-ef-row="33"] { --ef-row: 33; }
4713
+ :where(.ef-character-grid) [data-ef-row="34"] { --ef-row: 34; }
4714
+ :where(.ef-character-grid) [data-ef-row="35"] { --ef-row: 35; }
4715
+ :where(.ef-character-grid) [data-ef-row="36"] { --ef-row: 36; }
4716
+ :where(.ef-character-grid) [data-ef-row="37"] { --ef-row: 37; }
4717
+ :where(.ef-character-grid) [data-ef-row="38"] { --ef-row: 38; }
4718
+ :where(.ef-character-grid) [data-ef-row="39"] { --ef-row: 39; }
4719
+ :where(.ef-character-grid) [data-ef-row="40"] { --ef-row: 40; }
4720
+ :where(.ef-character-grid) [data-ef-row="41"] { --ef-row: 41; }
4721
+ :where(.ef-character-grid) [data-ef-row="42"] { --ef-row: 42; }
4722
+ :where(.ef-character-grid) [data-ef-row="43"] { --ef-row: 43; }
4723
+ :where(.ef-character-grid) [data-ef-row="44"] { --ef-row: 44; }
4724
+ :where(.ef-character-grid) [data-ef-row="45"] { --ef-row: 45; }
4725
+ :where(.ef-character-grid) [data-ef-row="46"] { --ef-row: 46; }
4726
+ :where(.ef-character-grid) [data-ef-row="47"] { --ef-row: 47; }
4727
+ :where(.ef-character-grid) [data-ef-row="48"] { --ef-row: 48; }
4728
+ :where(.ef-character-grid) [data-ef-row="49"] { --ef-row: 49; }
4729
+ :where(.ef-character-grid) [data-ef-row="50"] { --ef-row: 50; }
4730
+ :where(.ef-character-grid) [data-ef-row="51"] { --ef-row: 51; }
4731
+ :where(.ef-character-grid) [data-ef-row="52"] { --ef-row: 52; }
4732
+ :where(.ef-character-grid) [data-ef-col="1"] { --ef-col: 1; }
4733
+ :where(.ef-character-grid) [data-ef-col="2"] { --ef-col: 2; }
4734
+ :where(.ef-character-grid) [data-ef-col="3"] { --ef-col: 3; }
4735
+ :where(.ef-character-grid) [data-ef-col="4"] { --ef-col: 4; }
4736
+ :where(.ef-character-grid) [data-ef-col="5"] { --ef-col: 5; }
4737
+ :where(.ef-character-grid) [data-ef-col="6"] { --ef-col: 6; }
4738
+ :where(.ef-character-grid) [data-ef-col="7"] { --ef-col: 7; }
4739
+ :where(.ef-character-grid) [data-ef-col="8"] { --ef-col: 8; }
4740
+ :where(.ef-character-grid) [data-ef-col="9"] { --ef-col: 9; }
4741
+ :where(.ef-character-grid) [data-ef-col="10"] { --ef-col: 10; }
4742
+ :where(.ef-character-grid) [data-ef-col="11"] { --ef-col: 11; }
4743
+ :where(.ef-character-grid) [data-ef-col="12"] { --ef-col: 12; }
4744
+ :where(.ef-character-grid) [data-ef-col="13"] { --ef-col: 13; }
4745
+ :where(.ef-character-grid) [data-ef-col="14"] { --ef-col: 14; }
4746
+ :where(.ef-character-grid) [data-ef-col="15"] { --ef-col: 15; }
4747
+ :where(.ef-character-grid) [data-ef-col="16"] { --ef-col: 16; }
4748
+ :where(.ef-character-grid) [data-ef-col="17"] { --ef-col: 17; }
4749
+ :where(.ef-character-grid) [data-ef-col="18"] { --ef-col: 18; }
4750
+ :where(.ef-character-grid) [data-ef-col="19"] { --ef-col: 19; }
4751
+ :where(.ef-character-grid) [data-ef-col="20"] { --ef-col: 20; }
4752
+ :where(.ef-character-grid) [data-ef-col="21"] { --ef-col: 21; }
4753
+ :where(.ef-character-grid) [data-ef-col="22"] { --ef-col: 22; }
4754
+ :where(.ef-character-grid) [data-ef-col="23"] { --ef-col: 23; }
4755
+ :where(.ef-character-grid) [data-ef-col="24"] { --ef-col: 24; }
4756
+ :where(.ef-character-grid) [data-ef-col="25"] { --ef-col: 25; }
4757
+ :where(.ef-character-grid) [data-ef-col="26"] { --ef-col: 26; }
4758
+ :where(.ef-character-grid) [data-ef-col="27"] { --ef-col: 27; }
4759
+ :where(.ef-character-grid) [data-ef-col="28"] { --ef-col: 28; }
4760
+ :where(.ef-character-grid) [data-ef-col="29"] { --ef-col: 29; }
4761
+ :where(.ef-character-grid) [data-ef-col="30"] { --ef-col: 30; }
4762
+ :where(.ef-character-grid) [data-ef-col="31"] { --ef-col: 31; }
4763
+ :where(.ef-character-grid) [data-ef-col="32"] { --ef-col: 32; }
4764
+ :where(.ef-character-grid) [data-ef-col="33"] { --ef-col: 33; }
4765
+ :where(.ef-character-grid) [data-ef-col="34"] { --ef-col: 34; }
4766
+ :where(.ef-character-grid) [data-ef-col="35"] { --ef-col: 35; }
4767
+ :where(.ef-character-grid) [data-ef-col="36"] { --ef-col: 36; }
4768
+ :where(.ef-character-grid) [data-ef-col="37"] { --ef-col: 37; }
4769
+ :where(.ef-character-grid) [data-ef-col="38"] { --ef-col: 38; }
4770
+ :where(.ef-character-grid) [data-ef-col="39"] { --ef-col: 39; }
4771
+ :where(.ef-character-grid) [data-ef-col="40"] { --ef-col: 40; }
4772
+ :where(.ef-character-grid) [data-ef-col="41"] { --ef-col: 41; }
4773
+ :where(.ef-character-grid) [data-ef-col="42"] { --ef-col: 42; }
4774
+ :where(.ef-character-grid) [data-ef-col="43"] { --ef-col: 43; }
4775
+ :where(.ef-character-grid) [data-ef-col="44"] { --ef-col: 44; }
4776
+ :where(.ef-character-grid) [data-ef-col="45"] { --ef-col: 45; }
4777
+ :where(.ef-character-grid) [data-ef-col="46"] { --ef-col: 46; }
4778
+ :where(.ef-character-grid) [data-ef-col="47"] { --ef-col: 47; }
4779
+ :where(.ef-character-grid) [data-ef-col="48"] { --ef-col: 48; }
4780
+ :where(.ef-character-grid) [data-ef-col="49"] { --ef-col: 49; }
4781
+ :where(.ef-character-grid) [data-ef-col="50"] { --ef-col: 50; }
4782
+ :where(.ef-character-grid) [data-ef-col="51"] { --ef-col: 51; }
4783
+ :where(.ef-character-grid) [data-ef-col="52"] { --ef-col: 52; }
4784
+ :where(.ef-character-grid) [data-ef-col="53"] { --ef-col: 53; }
4785
+ :where(.ef-character-grid) [data-ef-col="54"] { --ef-col: 54; }
4786
+ :where(.ef-character-grid) [data-ef-col="55"] { --ef-col: 55; }
4787
+ :where(.ef-character-grid) [data-ef-col="56"] { --ef-col: 56; }
4788
+ :where(.ef-character-grid) [data-ef-col="57"] { --ef-col: 57; }
4789
+ :where(.ef-character-grid) [data-ef-col="58"] { --ef-col: 58; }
4790
+ :where(.ef-character-grid) [data-ef-col="59"] { --ef-col: 59; }
4791
+ :where(.ef-character-grid) [data-ef-col="60"] { --ef-col: 60; }
4792
+ :where(.ef-character-grid) [data-ef-col="61"] { --ef-col: 61; }
4793
+ :where(.ef-character-grid) [data-ef-col="62"] { --ef-col: 62; }
4794
+ :where(.ef-character-grid) [data-ef-col="63"] { --ef-col: 63; }
4795
+ :where(.ef-character-grid) [data-ef-col="64"] { --ef-col: 64; }
4796
+ :where(.ef-character-grid) [data-ef-col="65"] { --ef-col: 65; }
4797
+ :where(.ef-character-grid) [data-ef-col="66"] { --ef-col: 66; }
4798
+ :where(.ef-character-grid) [data-ef-col="67"] { --ef-col: 67; }
4799
+ :where(.ef-character-grid) [data-ef-col="68"] { --ef-col: 68; }
4800
+ :where(.ef-character-grid) [data-ef-col="69"] { --ef-col: 69; }
4801
+ :where(.ef-character-grid) [data-ef-col="70"] { --ef-col: 70; }
4802
+ :where(.ef-character-grid) [data-ef-col="71"] { --ef-col: 71; }
4803
+ :where(.ef-character-grid) [data-ef-col="72"] { --ef-col: 72; }
4804
+ :where(.ef-character-grid) [data-ef-col="73"] { --ef-col: 73; }
4805
+ :where(.ef-character-grid) [data-ef-col="74"] { --ef-col: 74; }
4806
+ :where(.ef-character-grid) [data-ef-col="75"] { --ef-col: 75; }
4807
+ :where(.ef-character-grid) [data-ef-col="76"] { --ef-col: 76; }
4808
+ :where(.ef-character-grid) [data-ef-col="77"] { --ef-col: 77; }
4809
+ :where(.ef-character-grid) [data-ef-col="78"] { --ef-col: 78; }
4810
+ :where(.ef-character-grid) [data-ef-col="79"] { --ef-col: 79; }
4811
+ :where(.ef-character-grid) [data-ef-col="80"] { --ef-col: 80; }
4812
+ :where(.ef-character-grid) [data-ef-col="81"] { --ef-col: 81; }
4813
+ :where(.ef-character-grid) [data-ef-col="82"] { --ef-col: 82; }
4814
+ :where(.ef-character-grid) [data-ef-col="83"] { --ef-col: 83; }
4815
+ :where(.ef-character-grid) [data-ef-col="84"] { --ef-col: 84; }
4816
+ :where(.ef-character-grid) [data-ef-col="85"] { --ef-col: 85; }
4817
+ :where(.ef-character-grid) [data-ef-col="86"] { --ef-col: 86; }
4818
+ :where(.ef-character-grid) [data-ef-col="87"] { --ef-col: 87; }
4819
+ :where(.ef-character-grid) [data-ef-col="88"] { --ef-col: 88; }
4820
+ :where(.ef-character-grid) [data-ef-col="89"] { --ef-col: 89; }
4821
+ :where(.ef-character-grid) [data-ef-col="90"] { --ef-col: 90; }
4822
+ :where(.ef-character-grid) [data-ef-col="91"] { --ef-col: 91; }
4823
+ :where(.ef-character-grid) [data-ef-col="92"] { --ef-col: 92; }
4824
+ :where(.ef-character-grid) [data-ef-col="93"] { --ef-col: 93; }
4825
+ :where(.ef-character-grid) [data-ef-col="94"] { --ef-col: 94; }
4826
+ :where(.ef-character-grid) [data-ef-col="95"] { --ef-col: 95; }
4827
+ :where(.ef-character-grid) [data-ef-col="96"] { --ef-col: 96; }
4828
+ :where(.ef-character-grid) [data-ef-col="97"] { --ef-col: 97; }
4829
+ :where(.ef-character-grid) [data-ef-col="98"] { --ef-col: 98; }
4830
+ :where(.ef-character-grid) [data-ef-col="99"] { --ef-col: 99; }
4831
+ :where(.ef-character-grid) [data-ef-col="100"] { --ef-col: 100; }
4832
+ :where(.ef-character-grid) [data-ef-col="101"] { --ef-col: 101; }
4833
+ :where(.ef-character-grid) [data-ef-col="102"] { --ef-col: 102; }
4834
+ :where(.ef-character-grid) [data-ef-col="103"] { --ef-col: 103; }
4835
+ :where(.ef-character-grid) [data-ef-col="104"] { --ef-col: 104; }
4836
+ :where(.ef-character-grid) [data-ef-col="105"] { --ef-col: 105; }
4837
+ :where(.ef-character-grid) [data-ef-col="106"] { --ef-col: 106; }
4838
+ :where(.ef-character-grid) [data-ef-col="107"] { --ef-col: 107; }
4839
+ :where(.ef-character-grid) [data-ef-col="108"] { --ef-col: 108; }
4840
+ :where(.ef-character-grid) [data-ef-col="109"] { --ef-col: 109; }
4841
+ :where(.ef-character-grid) [data-ef-col="110"] { --ef-col: 110; }
4842
+ :where(.ef-character-grid) [data-ef-col="111"] { --ef-col: 111; }
4843
+ :where(.ef-character-grid) [data-ef-col="112"] { --ef-col: 112; }
4844
+ :where(.ef-character-grid) [data-ef-col="113"] { --ef-col: 113; }
4845
+ :where(.ef-character-grid) [data-ef-col="114"] { --ef-col: 114; }
4846
+ :where(.ef-character-grid) [data-ef-col="115"] { --ef-col: 115; }
4847
+ :where(.ef-character-grid) [data-ef-col="116"] { --ef-col: 116; }
4848
+ :where(.ef-character-grid) [data-ef-col="117"] { --ef-col: 117; }
4849
+ :where(.ef-character-grid) [data-ef-col="118"] { --ef-col: 118; }
4850
+ :where(.ef-character-grid) [data-ef-col="119"] { --ef-col: 119; }
4851
+ :where(.ef-character-grid) [data-ef-col="120"] { --ef-col: 120; }
4852
+ :where(.ef-character-grid) [data-ef-col="121"] { --ef-col: 121; }
4853
+ :where(.ef-character-grid) [data-ef-col="122"] { --ef-col: 122; }
4854
+ :where(.ef-character-grid) [data-ef-col="123"] { --ef-col: 123; }
4855
+ :where(.ef-character-grid) [data-ef-col="124"] { --ef-col: 124; }
4856
+ :where(.ef-character-grid) [data-ef-col="125"] { --ef-col: 125; }
4857
+ :where(.ef-character-grid) [data-ef-col="126"] { --ef-col: 126; }
4858
+ :where(.ef-character-grid) [data-ef-col="127"] { --ef-col: 127; }
4859
+ :where(.ef-character-grid) [data-ef-col="128"] { --ef-col: 128; }
4860
+ :where(.ef-character-grid) [data-ef-col="129"] { --ef-col: 129; }
4861
+ :where(.ef-character-grid) [data-ef-col="130"] { --ef-col: 130; }
4862
+ :where(.ef-character-grid) [data-ef-col="131"] { --ef-col: 131; }
4863
+ :where(.ef-character-grid) [data-ef-col="132"] { --ef-col: 132; }
4864
+ :where(.ef-character-grid) [data-ef-len="1"] { --ef-len: 1; }
4865
+ :where(.ef-character-grid) [data-ef-len="2"] { --ef-len: 2; }
4866
+ :where(.ef-character-grid) [data-ef-len="3"] { --ef-len: 3; }
4867
+ :where(.ef-character-grid) [data-ef-len="4"] { --ef-len: 4; }
4868
+ :where(.ef-character-grid) [data-ef-len="5"] { --ef-len: 5; }
4869
+ :where(.ef-character-grid) [data-ef-len="6"] { --ef-len: 6; }
4870
+ :where(.ef-character-grid) [data-ef-len="7"] { --ef-len: 7; }
4871
+ :where(.ef-character-grid) [data-ef-len="8"] { --ef-len: 8; }
4872
+ :where(.ef-character-grid) [data-ef-len="9"] { --ef-len: 9; }
4873
+ :where(.ef-character-grid) [data-ef-len="10"] { --ef-len: 10; }
4874
+ :where(.ef-character-grid) [data-ef-len="11"] { --ef-len: 11; }
4875
+ :where(.ef-character-grid) [data-ef-len="12"] { --ef-len: 12; }
4876
+ :where(.ef-character-grid) [data-ef-len="13"] { --ef-len: 13; }
4877
+ :where(.ef-character-grid) [data-ef-len="14"] { --ef-len: 14; }
4878
+ :where(.ef-character-grid) [data-ef-len="15"] { --ef-len: 15; }
4879
+ :where(.ef-character-grid) [data-ef-len="16"] { --ef-len: 16; }
4880
+ :where(.ef-character-grid) [data-ef-len="17"] { --ef-len: 17; }
4881
+ :where(.ef-character-grid) [data-ef-len="18"] { --ef-len: 18; }
4882
+ :where(.ef-character-grid) [data-ef-len="19"] { --ef-len: 19; }
4883
+ :where(.ef-character-grid) [data-ef-len="20"] { --ef-len: 20; }
4884
+ :where(.ef-character-grid) [data-ef-len="21"] { --ef-len: 21; }
4885
+ :where(.ef-character-grid) [data-ef-len="22"] { --ef-len: 22; }
4886
+ :where(.ef-character-grid) [data-ef-len="23"] { --ef-len: 23; }
4887
+ :where(.ef-character-grid) [data-ef-len="24"] { --ef-len: 24; }
4888
+ :where(.ef-character-grid) [data-ef-len="25"] { --ef-len: 25; }
4889
+ :where(.ef-character-grid) [data-ef-len="26"] { --ef-len: 26; }
4890
+ :where(.ef-character-grid) [data-ef-len="27"] { --ef-len: 27; }
4891
+ :where(.ef-character-grid) [data-ef-len="28"] { --ef-len: 28; }
4892
+ :where(.ef-character-grid) [data-ef-len="29"] { --ef-len: 29; }
4893
+ :where(.ef-character-grid) [data-ef-len="30"] { --ef-len: 30; }
4894
+ :where(.ef-character-grid) [data-ef-len="31"] { --ef-len: 31; }
4895
+ :where(.ef-character-grid) [data-ef-len="32"] { --ef-len: 32; }
4896
+ :where(.ef-character-grid) [data-ef-len="33"] { --ef-len: 33; }
4897
+ :where(.ef-character-grid) [data-ef-len="34"] { --ef-len: 34; }
4898
+ :where(.ef-character-grid) [data-ef-len="35"] { --ef-len: 35; }
4899
+ :where(.ef-character-grid) [data-ef-len="36"] { --ef-len: 36; }
4900
+ :where(.ef-character-grid) [data-ef-len="37"] { --ef-len: 37; }
4901
+ :where(.ef-character-grid) [data-ef-len="38"] { --ef-len: 38; }
4902
+ :where(.ef-character-grid) [data-ef-len="39"] { --ef-len: 39; }
4903
+ :where(.ef-character-grid) [data-ef-len="40"] { --ef-len: 40; }
4904
+ :where(.ef-character-grid) [data-ef-len="41"] { --ef-len: 41; }
4905
+ :where(.ef-character-grid) [data-ef-len="42"] { --ef-len: 42; }
4906
+ :where(.ef-character-grid) [data-ef-len="43"] { --ef-len: 43; }
4907
+ :where(.ef-character-grid) [data-ef-len="44"] { --ef-len: 44; }
4908
+ :where(.ef-character-grid) [data-ef-len="45"] { --ef-len: 45; }
4909
+ :where(.ef-character-grid) [data-ef-len="46"] { --ef-len: 46; }
4910
+ :where(.ef-character-grid) [data-ef-len="47"] { --ef-len: 47; }
4911
+ :where(.ef-character-grid) [data-ef-len="48"] { --ef-len: 48; }
4912
+ :where(.ef-character-grid) [data-ef-len="49"] { --ef-len: 49; }
4913
+ :where(.ef-character-grid) [data-ef-len="50"] { --ef-len: 50; }
4914
+ :where(.ef-character-grid) [data-ef-len="51"] { --ef-len: 51; }
4915
+ :where(.ef-character-grid) [data-ef-len="52"] { --ef-len: 52; }
4916
+ :where(.ef-character-grid) [data-ef-len="53"] { --ef-len: 53; }
4917
+ :where(.ef-character-grid) [data-ef-len="54"] { --ef-len: 54; }
4918
+ :where(.ef-character-grid) [data-ef-len="55"] { --ef-len: 55; }
4919
+ :where(.ef-character-grid) [data-ef-len="56"] { --ef-len: 56; }
4920
+ :where(.ef-character-grid) [data-ef-len="57"] { --ef-len: 57; }
4921
+ :where(.ef-character-grid) [data-ef-len="58"] { --ef-len: 58; }
4922
+ :where(.ef-character-grid) [data-ef-len="59"] { --ef-len: 59; }
4923
+ :where(.ef-character-grid) [data-ef-len="60"] { --ef-len: 60; }
4924
+ :where(.ef-character-grid) [data-ef-len="61"] { --ef-len: 61; }
4925
+ :where(.ef-character-grid) [data-ef-len="62"] { --ef-len: 62; }
4926
+ :where(.ef-character-grid) [data-ef-len="63"] { --ef-len: 63; }
4927
+ :where(.ef-character-grid) [data-ef-len="64"] { --ef-len: 64; }
4928
+ :where(.ef-character-grid) [data-ef-len="65"] { --ef-len: 65; }
4929
+ :where(.ef-character-grid) [data-ef-len="66"] { --ef-len: 66; }
4930
+ :where(.ef-character-grid) [data-ef-len="67"] { --ef-len: 67; }
4931
+ :where(.ef-character-grid) [data-ef-len="68"] { --ef-len: 68; }
4932
+ :where(.ef-character-grid) [data-ef-len="69"] { --ef-len: 69; }
4933
+ :where(.ef-character-grid) [data-ef-len="70"] { --ef-len: 70; }
4934
+ :where(.ef-character-grid) [data-ef-len="71"] { --ef-len: 71; }
4935
+ :where(.ef-character-grid) [data-ef-len="72"] { --ef-len: 72; }
4936
+ :where(.ef-character-grid) [data-ef-len="73"] { --ef-len: 73; }
4937
+ :where(.ef-character-grid) [data-ef-len="74"] { --ef-len: 74; }
4938
+ :where(.ef-character-grid) [data-ef-len="75"] { --ef-len: 75; }
4939
+ :where(.ef-character-grid) [data-ef-len="76"] { --ef-len: 76; }
4940
+ :where(.ef-character-grid) [data-ef-len="77"] { --ef-len: 77; }
4941
+ :where(.ef-character-grid) [data-ef-len="78"] { --ef-len: 78; }
4942
+ :where(.ef-character-grid) [data-ef-len="79"] { --ef-len: 79; }
4943
+ :where(.ef-character-grid) [data-ef-len="80"] { --ef-len: 80; }
4944
+ :where(.ef-character-grid) [data-ef-len="81"] { --ef-len: 81; }
4945
+ :where(.ef-character-grid) [data-ef-len="82"] { --ef-len: 82; }
4946
+ :where(.ef-character-grid) [data-ef-len="83"] { --ef-len: 83; }
4947
+ :where(.ef-character-grid) [data-ef-len="84"] { --ef-len: 84; }
4948
+ :where(.ef-character-grid) [data-ef-len="85"] { --ef-len: 85; }
4949
+ :where(.ef-character-grid) [data-ef-len="86"] { --ef-len: 86; }
4950
+ :where(.ef-character-grid) [data-ef-len="87"] { --ef-len: 87; }
4951
+ :where(.ef-character-grid) [data-ef-len="88"] { --ef-len: 88; }
4952
+ :where(.ef-character-grid) [data-ef-len="89"] { --ef-len: 89; }
4953
+ :where(.ef-character-grid) [data-ef-len="90"] { --ef-len: 90; }
4954
+ :where(.ef-character-grid) [data-ef-len="91"] { --ef-len: 91; }
4955
+ :where(.ef-character-grid) [data-ef-len="92"] { --ef-len: 92; }
4956
+ :where(.ef-character-grid) [data-ef-len="93"] { --ef-len: 93; }
4957
+ :where(.ef-character-grid) [data-ef-len="94"] { --ef-len: 94; }
4958
+ :where(.ef-character-grid) [data-ef-len="95"] { --ef-len: 95; }
4959
+ :where(.ef-character-grid) [data-ef-len="96"] { --ef-len: 96; }
4960
+ :where(.ef-character-grid) [data-ef-len="97"] { --ef-len: 97; }
4961
+ :where(.ef-character-grid) [data-ef-len="98"] { --ef-len: 98; }
4962
+ :where(.ef-character-grid) [data-ef-len="99"] { --ef-len: 99; }
4963
+ :where(.ef-character-grid) [data-ef-len="100"] { --ef-len: 100; }
4964
+ :where(.ef-character-grid) [data-ef-len="101"] { --ef-len: 101; }
4965
+ :where(.ef-character-grid) [data-ef-len="102"] { --ef-len: 102; }
4966
+ :where(.ef-character-grid) [data-ef-len="103"] { --ef-len: 103; }
4967
+ :where(.ef-character-grid) [data-ef-len="104"] { --ef-len: 104; }
4968
+ :where(.ef-character-grid) [data-ef-len="105"] { --ef-len: 105; }
4969
+ :where(.ef-character-grid) [data-ef-len="106"] { --ef-len: 106; }
4970
+ :where(.ef-character-grid) [data-ef-len="107"] { --ef-len: 107; }
4971
+ :where(.ef-character-grid) [data-ef-len="108"] { --ef-len: 108; }
4972
+ :where(.ef-character-grid) [data-ef-len="109"] { --ef-len: 109; }
4973
+ :where(.ef-character-grid) [data-ef-len="110"] { --ef-len: 110; }
4974
+ :where(.ef-character-grid) [data-ef-len="111"] { --ef-len: 111; }
4975
+ :where(.ef-character-grid) [data-ef-len="112"] { --ef-len: 112; }
4976
+ :where(.ef-character-grid) [data-ef-len="113"] { --ef-len: 113; }
4977
+ :where(.ef-character-grid) [data-ef-len="114"] { --ef-len: 114; }
4978
+ :where(.ef-character-grid) [data-ef-len="115"] { --ef-len: 115; }
4979
+ :where(.ef-character-grid) [data-ef-len="116"] { --ef-len: 116; }
4980
+ :where(.ef-character-grid) [data-ef-len="117"] { --ef-len: 117; }
4981
+ :where(.ef-character-grid) [data-ef-len="118"] { --ef-len: 118; }
4982
+ :where(.ef-character-grid) [data-ef-len="119"] { --ef-len: 119; }
4983
+ :where(.ef-character-grid) [data-ef-len="120"] { --ef-len: 120; }
4984
+ :where(.ef-character-grid) [data-ef-len="121"] { --ef-len: 121; }
4985
+ :where(.ef-character-grid) [data-ef-len="122"] { --ef-len: 122; }
4986
+ :where(.ef-character-grid) [data-ef-len="123"] { --ef-len: 123; }
4987
+ :where(.ef-character-grid) [data-ef-len="124"] { --ef-len: 124; }
4988
+ :where(.ef-character-grid) [data-ef-len="125"] { --ef-len: 125; }
4989
+ :where(.ef-character-grid) [data-ef-len="126"] { --ef-len: 126; }
4990
+ :where(.ef-character-grid) [data-ef-len="127"] { --ef-len: 127; }
4991
+ :where(.ef-character-grid) [data-ef-len="128"] { --ef-len: 128; }
4992
+ :where(.ef-character-grid) [data-ef-len="129"] { --ef-len: 129; }
4993
+ :where(.ef-character-grid) [data-ef-len="130"] { --ef-len: 130; }
4994
+ :where(.ef-character-grid) [data-ef-len="131"] { --ef-len: 131; }
4995
+ :where(.ef-character-grid) [data-ef-len="132"] { --ef-len: 132; }
4996
+ :where(.ef-character-grid) [data-ef-height="1"] { --ef-height: 1; }
4997
+ :where(.ef-character-grid) [data-ef-height="2"] { --ef-height: 2; }
4998
+ :where(.ef-character-grid) [data-ef-height="3"] { --ef-height: 3; }
4999
+ :where(.ef-character-grid) [data-ef-height="4"] { --ef-height: 4; }
5000
+ :where(.ef-character-grid) [data-ef-height="5"] { --ef-height: 5; }
5001
+ :where(.ef-character-grid) [data-ef-height="6"] { --ef-height: 6; }
5002
+ :where(.ef-character-grid) [data-ef-height="7"] { --ef-height: 7; }
5003
+ :where(.ef-character-grid) [data-ef-height="8"] { --ef-height: 8; }
5004
+ :where(.ef-character-grid) [data-ef-height="9"] { --ef-height: 9; }
5005
+ :where(.ef-character-grid) [data-ef-height="10"] { --ef-height: 10; }
5006
+ :where(.ef-character-grid) [data-ef-height="11"] { --ef-height: 11; }
5007
+ :where(.ef-character-grid) [data-ef-height="12"] { --ef-height: 12; }
5008
+ :where(.ef-character-grid) [data-ef-height="13"] { --ef-height: 13; }
5009
+ :where(.ef-character-grid) [data-ef-height="14"] { --ef-height: 14; }
5010
+ :where(.ef-character-grid) [data-ef-height="15"] { --ef-height: 15; }
5011
+ :where(.ef-character-grid) [data-ef-height="16"] { --ef-height: 16; }
5012
+ :where(.ef-character-grid) [data-ef-height="17"] { --ef-height: 17; }
5013
+ :where(.ef-character-grid) [data-ef-height="18"] { --ef-height: 18; }
5014
+ :where(.ef-character-grid) [data-ef-height="19"] { --ef-height: 19; }
5015
+ :where(.ef-character-grid) [data-ef-height="20"] { --ef-height: 20; }
5016
+ :where(.ef-character-grid) [data-ef-height="21"] { --ef-height: 21; }
5017
+ :where(.ef-character-grid) [data-ef-height="22"] { --ef-height: 22; }
5018
+ :where(.ef-character-grid) [data-ef-height="23"] { --ef-height: 23; }
5019
+ :where(.ef-character-grid) [data-ef-height="24"] { --ef-height: 24; }
5020
+ :where(.ef-character-grid) [data-ef-height="25"] { --ef-height: 25; }
5021
+ :where(.ef-character-grid) [data-ef-height="26"] { --ef-height: 26; }
5022
+ :where(.ef-character-grid) [data-ef-height="27"] { --ef-height: 27; }
5023
+ :where(.ef-character-grid) [data-ef-height="28"] { --ef-height: 28; }
5024
+ :where(.ef-character-grid) [data-ef-height="29"] { --ef-height: 29; }
5025
+ :where(.ef-character-grid) [data-ef-height="30"] { --ef-height: 30; }
5026
+ :where(.ef-character-grid) [data-ef-height="31"] { --ef-height: 31; }
5027
+ :where(.ef-character-grid) [data-ef-height="32"] { --ef-height: 32; }
5028
+ :where(.ef-character-grid) [data-ef-height="33"] { --ef-height: 33; }
5029
+ :where(.ef-character-grid) [data-ef-height="34"] { --ef-height: 34; }
5030
+ :where(.ef-character-grid) [data-ef-height="35"] { --ef-height: 35; }
5031
+ :where(.ef-character-grid) [data-ef-height="36"] { --ef-height: 36; }
5032
+ :where(.ef-character-grid) [data-ef-height="37"] { --ef-height: 37; }
5033
+ :where(.ef-character-grid) [data-ef-height="38"] { --ef-height: 38; }
5034
+ :where(.ef-character-grid) [data-ef-height="39"] { --ef-height: 39; }
5035
+ :where(.ef-character-grid) [data-ef-height="40"] { --ef-height: 40; }
5036
+ :where(.ef-character-grid) [data-ef-height="41"] { --ef-height: 41; }
5037
+ :where(.ef-character-grid) [data-ef-height="42"] { --ef-height: 42; }
5038
+ :where(.ef-character-grid) [data-ef-height="43"] { --ef-height: 43; }
5039
+ :where(.ef-character-grid) [data-ef-height="44"] { --ef-height: 44; }
5040
+ :where(.ef-character-grid) [data-ef-height="45"] { --ef-height: 45; }
5041
+ :where(.ef-character-grid) [data-ef-height="46"] { --ef-height: 46; }
5042
+ :where(.ef-character-grid) [data-ef-height="47"] { --ef-height: 47; }
5043
+ :where(.ef-character-grid) [data-ef-height="48"] { --ef-height: 48; }
5044
+ :where(.ef-character-grid) [data-ef-height="49"] { --ef-height: 49; }
5045
+ :where(.ef-character-grid) [data-ef-height="50"] { --ef-height: 50; }
5046
+ :where(.ef-character-grid) [data-ef-gutter="0"] { --ef-gutter: 0; }
5047
+ :where(.ef-character-grid) [data-ef-gutter="1"] { --ef-gutter: 1; }
5048
+ :where(.ef-character-grid) [data-ef-gutter="2"] { --ef-gutter: 2; }
5049
+ :where(.ef-character-grid) [data-ef-gutter="3"] { --ef-gutter: 3; }
5050
+ :where(.ef-character-grid) [data-ef-gutter="4"] { --ef-gutter: 4; }
5051
+ /* END generated: character-grid coordinates */
5052
+ }