@echelon-foundry/design-system 0.7.0 → 0.8.0-main.250.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.
- package/CHANGELOG.md +16 -0
- package/LICENSE +131 -21
- package/README.md +5 -0
- package/contracts/design-capabilities.json +13 -0
- package/dist/all.css +61 -1
- package/dist/build-metrics.json +5 -3
- package/dist/components.css +33 -1
- package/dist/foundations.css +28 -0
- package/dist/icons/registry.json +1 -1
- package/dist/marketing/forma-all.css +62 -2
- package/dist/marketing/forma-echelon-marketing.css +29 -1
- package/dist/marketing/forma-marketing-theme-echelon.css +1 -1
- package/dist/marketing/forma-marketing.css +29 -1
- package/dist/marketing/forma-marketing.manifest.json +9 -9
- package/dist/marketing/forma-marketing.sha256 +4 -4
- package/dist/patterns/form.html +19 -0
- package/docs/DESIGN-CONTRACT.md +48 -0
- package/examples/design/invalid/invalid-parent-child.forma-design.json +36 -0
- package/examples/design/invalid/misaligned-standard-fields.forma-design.json +36 -0
- package/examples/design/invalid/missing-action-binding.forma-design.json +35 -0
- package/examples/design/invalid/unsupported-standard-override.forma-design.json +36 -0
- package/examples/design/invalid/unsupported-version.forma-design.json +35 -0
- package/examples/design/valid/customer-form.forma-design.json +97 -0
- package/figma/component-contracts.json +10 -0
- package/package.json +14 -4
- package/patterns/form.html +19 -0
- package/schemas/design/1.0/forma-design.schema.json +191 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,22 @@ published as GitHub release tarballs
|
|
|
7
7
|
and to npm. Earlier releases are described in `docs/CONSUMING-FORMA.md` and
|
|
8
8
|
`HANDOFF.md`.
|
|
9
9
|
|
|
10
|
+
## 0.8.0
|
|
11
|
+
|
|
12
|
+
Minor release: Design by Construction forms and fully operable form examples.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- A versioned `forma.design/1.0.0` JSON contract, capability declaration, validator, deterministic HTML renderer, valid NASA fixture and refusal fixtures for unsupported versions, presentation overrides, invalid nesting, misalignment and unbound actions.
|
|
16
|
+
- A complete form catalog page with functional basic, advanced, validation and mobile examples built from native custom-element HTML.
|
|
17
|
+
- Package exports for the design schema, capabilities and examples, while preserving hand-authored HTML and audited extended/custom escape paths.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- Forms now have a bounded responsive root, aligned grid-field tracks, stable validation-message placement and visible fragment-targeted success feedback.
|
|
21
|
+
- Native controls and buttons have explicit disabled, read-only and invalid presentation without relying on colour alone.
|
|
22
|
+
- Catalog reset examples are outcome-tested by preparing and observing a native field value; submit examples remain URL-outcome tested.
|
|
23
|
+
|
|
24
|
+
No existing component, class, token or icon was renamed or removed. Forma remains zero-runtime HTML and CSS; design validation and rendering are build-time tools.
|
|
25
|
+
|
|
10
26
|
## 0.7.0
|
|
11
27
|
|
|
12
28
|
Minor release: shared layout and interaction conformance with
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,131 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
to
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
# PolyForm Noncommercial License 1.0.0
|
|
2
|
+
|
|
3
|
+
<https://polyformproject.org/licenses/noncommercial/1.0.0>
|
|
4
|
+
|
|
5
|
+
## Acceptance
|
|
6
|
+
|
|
7
|
+
In order to get any license under these terms, you must agree
|
|
8
|
+
to them as both strict obligations and conditions to all
|
|
9
|
+
your licenses.
|
|
10
|
+
|
|
11
|
+
## Copyright License
|
|
12
|
+
|
|
13
|
+
The licensor grants you a copyright license for the
|
|
14
|
+
software to do everything you might do with the software
|
|
15
|
+
that would otherwise infringe the licensor's copyright
|
|
16
|
+
in it for any permitted purpose. However, you may
|
|
17
|
+
only distribute the software according to [Distribution
|
|
18
|
+
License](#distribution-license) and make changes or new works
|
|
19
|
+
based on the software according to [Changes and New Works
|
|
20
|
+
License](#changes-and-new-works-license).
|
|
21
|
+
|
|
22
|
+
## Distribution License
|
|
23
|
+
|
|
24
|
+
The licensor grants you an additional copyright license
|
|
25
|
+
to distribute copies of the software. Your license
|
|
26
|
+
to distribute covers distributing the software with
|
|
27
|
+
changes and new works permitted by [Changes and New Works
|
|
28
|
+
License](#changes-and-new-works-license).
|
|
29
|
+
|
|
30
|
+
## Notices
|
|
31
|
+
|
|
32
|
+
You must ensure that anyone who gets a copy of any part of
|
|
33
|
+
the software from you also gets a copy of these terms or the
|
|
34
|
+
URL for them above, as well as copies of any plain-text lines
|
|
35
|
+
beginning with `Required Notice:` that the licensor provided
|
|
36
|
+
with the software. For example:
|
|
37
|
+
|
|
38
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
39
|
+
|
|
40
|
+
## Changes and New Works License
|
|
41
|
+
|
|
42
|
+
The licensor grants you an additional copyright license to
|
|
43
|
+
make changes and new works based on the software for any
|
|
44
|
+
permitted purpose.
|
|
45
|
+
|
|
46
|
+
## Patent License
|
|
47
|
+
|
|
48
|
+
The licensor grants you a patent license for the software that
|
|
49
|
+
covers patent claims the licensor can license, or becomes able
|
|
50
|
+
to license, that you would infringe by using the software.
|
|
51
|
+
|
|
52
|
+
## Noncommercial Purposes
|
|
53
|
+
|
|
54
|
+
Any noncommercial purpose is a permitted purpose.
|
|
55
|
+
|
|
56
|
+
## Personal Uses
|
|
57
|
+
|
|
58
|
+
Personal use for research, experiment, and testing for
|
|
59
|
+
the benefit of public knowledge, personal study, private
|
|
60
|
+
entertainment, hobby projects, amateur pursuits, or religious
|
|
61
|
+
observance, without any anticipated commercial application,
|
|
62
|
+
is use for a permitted purpose.
|
|
63
|
+
|
|
64
|
+
## Noncommercial Organizations
|
|
65
|
+
|
|
66
|
+
Use by any charitable organization, educational institution,
|
|
67
|
+
public research organization, public safety or health
|
|
68
|
+
organization, environmental protection organization,
|
|
69
|
+
or government institution is use for a permitted purpose
|
|
70
|
+
regardless of the source of funding or obligations resulting
|
|
71
|
+
from the funding.
|
|
72
|
+
|
|
73
|
+
## Fair Use
|
|
74
|
+
|
|
75
|
+
You may have "fair use" rights for the software under the
|
|
76
|
+
law. These terms do not limit them.
|
|
77
|
+
|
|
78
|
+
## No Other Rights
|
|
79
|
+
|
|
80
|
+
These terms do not allow you to sublicense or transfer any of
|
|
81
|
+
your licenses to anyone else, or prevent the licensor from
|
|
82
|
+
granting licenses to anyone else. These terms do not imply
|
|
83
|
+
any other licenses.
|
|
84
|
+
|
|
85
|
+
## Patent Defense
|
|
86
|
+
|
|
87
|
+
If you make any written claim that the software infringes or
|
|
88
|
+
contributes to infringement of any patent, your patent license
|
|
89
|
+
for the software granted under these terms ends immediately. If
|
|
90
|
+
your company makes such a claim, your patent license ends
|
|
91
|
+
immediately for work on behalf of your company.
|
|
92
|
+
|
|
93
|
+
## Violations
|
|
94
|
+
|
|
95
|
+
The first time you are notified in writing that you have
|
|
96
|
+
violated any of these terms, or done anything with the software
|
|
97
|
+
not covered by your licenses, your licenses can nonetheless
|
|
98
|
+
continue if you come into full compliance with these terms,
|
|
99
|
+
and take practical steps to correct past violations, within
|
|
100
|
+
32 days of receiving notice. Otherwise, all your licenses
|
|
101
|
+
end immediately.
|
|
102
|
+
|
|
103
|
+
## No Liability
|
|
104
|
+
|
|
105
|
+
***As far as the law allows, the software comes as is, without
|
|
106
|
+
any warranty or condition, and the licensor will not be liable
|
|
107
|
+
to you for any damages arising out of these terms or the use
|
|
108
|
+
or nature of the software, under any kind of legal claim.***
|
|
109
|
+
|
|
110
|
+
## Definitions
|
|
111
|
+
|
|
112
|
+
The **licensor** is the individual or entity offering these
|
|
113
|
+
terms, and the **software** is the software the licensor makes
|
|
114
|
+
available under these terms.
|
|
115
|
+
|
|
116
|
+
**You** refers to the individual or entity agreeing to these
|
|
117
|
+
terms.
|
|
118
|
+
|
|
119
|
+
**Your company** is any legal entity, sole proprietorship,
|
|
120
|
+
or other kind of organization that you work for, plus all
|
|
121
|
+
organizations that have control over, are under the control of,
|
|
122
|
+
or are under common control with that organization. **Control**
|
|
123
|
+
means ownership of substantially all the assets of an entity,
|
|
124
|
+
or the power to direct its management and policies by vote,
|
|
125
|
+
contract, or otherwise. Control can be direct or indirect.
|
|
126
|
+
|
|
127
|
+
**Your licenses** are all the licenses granted to you for the
|
|
128
|
+
software under these terms.
|
|
129
|
+
|
|
130
|
+
**Use** means anything you do with the software requiring one
|
|
131
|
+
of your licenses.
|
package/README.md
CHANGED
|
@@ -155,3 +155,8 @@ See [docs/FIGMA.md](docs/FIGMA.md) for the variable, component, and Code Connect
|
|
|
155
155
|
workflow. The public package also exposes `./tokens.json` and
|
|
156
156
|
`./figma/components.json` for design tooling.
|
|
157
157
|
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
Source available under PolyForm Noncommercial 1.0.0 for permitted noncommercial uses. Commercial use requires a separate license from Echelon Foundry. Previously distributed versions remain subject to the licenses under which they were released.
|
|
161
|
+
|
|
162
|
+
Commercial licensing information is forthcoming.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "forma.design-capabilities",
|
|
3
|
+
"schemaVersion": "1.0.0",
|
|
4
|
+
"contractVersions": ["1.0.0"],
|
|
5
|
+
"modes": ["standard", "extended", "custom"],
|
|
6
|
+
"formLayouts": ["stack", "grid"],
|
|
7
|
+
"catalogLayoutModels": ["stack", "grid", "split", "dock", "flow", "canvas", "overlay", "page", "repeater"],
|
|
8
|
+
"controls": ["text", "email", "tel", "url", "number", "date", "time", "datetime-local", "textarea", "select", "checkbox", "radio-group", "toggle"],
|
|
9
|
+
"standardActionBindings": ["form.submit", "form.reset"],
|
|
10
|
+
"minimumViewportCssPx": 320,
|
|
11
|
+
"standardOverflow": "wrap",
|
|
12
|
+
"runtime": "none"
|
|
13
|
+
}
|
package/dist/all.css
CHANGED
|
@@ -631,6 +631,12 @@
|
|
|
631
631
|
transition-duration: var(--ef-motion-direct-duration, 0ms);
|
|
632
632
|
}
|
|
633
633
|
|
|
634
|
+
:where(button, .ef-button):disabled {
|
|
635
|
+
border-style: dashed;
|
|
636
|
+
cursor: not-allowed;
|
|
637
|
+
opacity: 0.62;
|
|
638
|
+
}
|
|
639
|
+
|
|
634
640
|
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) {
|
|
635
641
|
box-sizing: border-box;
|
|
636
642
|
min-block-size: 2.75rem;
|
|
@@ -686,6 +692,28 @@
|
|
|
686
692
|
text-align: start;
|
|
687
693
|
}
|
|
688
694
|
|
|
695
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):disabled {
|
|
696
|
+
--ef-color-text-secondary: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
697
|
+
--ef-color-text-muted: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
698
|
+
--ef-surface-accent-text-color: var(--ef-color-text-primary, #171a18);
|
|
699
|
+
border-style: dashed;
|
|
700
|
+
background: var(--ef-color-surface-secondary, #e3e0d7);
|
|
701
|
+
cursor: not-allowed;
|
|
702
|
+
opacity: 0.62;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea):read-only:not(:disabled) {
|
|
706
|
+
border-style: dashed;
|
|
707
|
+
background: color-mix(in srgb, var(--ef-color-surface-secondary, #e3e0d7) 55%, transparent);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/* Invalid state keeps native semantics and adds a shape cue. The associated
|
|
711
|
+
recovery message remains the non-colour explanation of what to fix. */
|
|
712
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):where([aria-invalid="true"], :user-invalid) {
|
|
713
|
+
border-inline-start-width: 0.3rem;
|
|
714
|
+
border-inline-start-color: var(--ef-color-status-danger, #8d3027);
|
|
715
|
+
}
|
|
716
|
+
|
|
689
717
|
:where(:focus-visible) {
|
|
690
718
|
outline: 3px solid var(--ef-color-focus-gap, #f2efe7);
|
|
691
719
|
outline-offset: 2px;
|
|
@@ -870,6 +898,39 @@
|
|
|
870
898
|
.ef-form-row > .ef-field > :not(.ef-field__label, .ef-field__description, .ef-validation-message) { grid-row: 3; margin-block-start: var(--ef-primitive-spacing-2, 0.5rem); }
|
|
871
899
|
.ef-form-row > .ef-field > .ef-validation-message { grid-row: 4; margin-block-start: var(--ef-primitive-spacing-2, 0.5rem); }
|
|
872
900
|
|
|
901
|
+
/* Form contract ------------------------------------------------------- */
|
|
902
|
+
.ef-form {
|
|
903
|
+
container-type: inline-size;
|
|
904
|
+
display: grid;
|
|
905
|
+
gap: var(--ef-form-gap, var(--ef-primitive-spacing-5, 1.5rem));
|
|
906
|
+
min-inline-size: 0;
|
|
907
|
+
max-inline-size: var(--ef-form-max, 64rem);
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
.ef-form > :where(h1, h2, h3, p) { margin-block: 0; }
|
|
911
|
+
|
|
912
|
+
/* Native constraint validation owns validity. The recovery text is in the
|
|
913
|
+
DOM and programmatically associated from first render, but appears only
|
|
914
|
+
after the browser marks the control user-invalid. */
|
|
915
|
+
.ef-validation-message--when-invalid { display: none; }
|
|
916
|
+
.ef-field:has(> :user-invalid) > .ef-validation-message--when-invalid { display: flex; }
|
|
917
|
+
|
|
918
|
+
/* GET submission to the declared fragment is a real, script-free outcome.
|
|
919
|
+
The status remains absent from layout and the accessibility tree until it
|
|
920
|
+
is the URL target. */
|
|
921
|
+
.ef-form__outcome { display: none; }
|
|
922
|
+
.ef-form__outcome:target {
|
|
923
|
+
--ef-color-text-secondary: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
924
|
+
--ef-color-text-muted: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
925
|
+
--ef-surface-accent-text-color: var(--ef-color-text-primary, #171a18);
|
|
926
|
+
display: block;
|
|
927
|
+
padding: var(--ef-primitive-spacing-3, 0.75rem);
|
|
928
|
+
border-inline-start: 0.25rem solid var(--ef-color-status-success, #2f6f4e);
|
|
929
|
+
background: var(--ef-color-surface-secondary, #e3e0d7);
|
|
930
|
+
color: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
931
|
+
font-weight: 650;
|
|
932
|
+
}
|
|
933
|
+
|
|
873
934
|
.ef-field > :is(input[type="date"], input[type="time"], input[type="datetime-local"]) {
|
|
874
935
|
min-inline-size: 0;
|
|
875
936
|
inline-size: 100%;
|
|
@@ -6235,7 +6296,6 @@
|
|
|
6235
6296
|
}
|
|
6236
6297
|
}
|
|
6237
6298
|
|
|
6238
|
-
|
|
6239
6299
|
@layer echelon.assessment {
|
|
6240
6300
|
/* Question shell ------------------------------------------------------ */
|
|
6241
6301
|
.ef-question {
|
package/dist/build-metrics.json
CHANGED
|
@@ -232,6 +232,7 @@
|
|
|
232
232
|
"patterns/flyout.html",
|
|
233
233
|
"patterns/focus-stage.html",
|
|
234
234
|
"patterns/form-row.html",
|
|
235
|
+
"patterns/form.html",
|
|
235
236
|
"patterns/frame.html",
|
|
236
237
|
"patterns/freshness.html",
|
|
237
238
|
"patterns/grid.html",
|
|
@@ -340,13 +341,13 @@
|
|
|
340
341
|
"tokens.css"
|
|
341
342
|
],
|
|
342
343
|
"bytes": {
|
|
343
|
-
"all.css":
|
|
344
|
+
"all.css": 329656,
|
|
344
345
|
"assessment.css": 36343,
|
|
345
346
|
"brands/echelon.css": 3621,
|
|
346
347
|
"brands/example-harbor.css": 3637,
|
|
347
348
|
"brands/index.json": 335,
|
|
348
|
-
"components.css":
|
|
349
|
-
"foundations.css":
|
|
349
|
+
"components.css": 210904,
|
|
350
|
+
"foundations.css": 15326,
|
|
350
351
|
"icons/add.svg": 216,
|
|
351
352
|
"icons/agent.svg": 354,
|
|
352
353
|
"icons/archive.svg": 248,
|
|
@@ -572,6 +573,7 @@
|
|
|
572
573
|
"patterns/flyout.html": 2488,
|
|
573
574
|
"patterns/focus-stage.html": 377,
|
|
574
575
|
"patterns/form-row.html": 848,
|
|
576
|
+
"patterns/form.html": 2000,
|
|
575
577
|
"patterns/frame.html": 365,
|
|
576
578
|
"patterns/freshness.html": 187,
|
|
577
579
|
"patterns/grid.html": 305,
|
package/dist/components.css
CHANGED
|
@@ -64,6 +64,39 @@
|
|
|
64
64
|
.ef-form-row > .ef-field > :not(.ef-field__label, .ef-field__description, .ef-validation-message) { grid-row: 3; margin-block-start: var(--ef-primitive-spacing-2, 0.5rem); }
|
|
65
65
|
.ef-form-row > .ef-field > .ef-validation-message { grid-row: 4; margin-block-start: var(--ef-primitive-spacing-2, 0.5rem); }
|
|
66
66
|
|
|
67
|
+
/* Form contract ------------------------------------------------------- */
|
|
68
|
+
.ef-form {
|
|
69
|
+
container-type: inline-size;
|
|
70
|
+
display: grid;
|
|
71
|
+
gap: var(--ef-form-gap, var(--ef-primitive-spacing-5, 1.5rem));
|
|
72
|
+
min-inline-size: 0;
|
|
73
|
+
max-inline-size: var(--ef-form-max, 64rem);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.ef-form > :where(h1, h2, h3, p) { margin-block: 0; }
|
|
77
|
+
|
|
78
|
+
/* Native constraint validation owns validity. The recovery text is in the
|
|
79
|
+
DOM and programmatically associated from first render, but appears only
|
|
80
|
+
after the browser marks the control user-invalid. */
|
|
81
|
+
.ef-validation-message--when-invalid { display: none; }
|
|
82
|
+
.ef-field:has(> :user-invalid) > .ef-validation-message--when-invalid { display: flex; }
|
|
83
|
+
|
|
84
|
+
/* GET submission to the declared fragment is a real, script-free outcome.
|
|
85
|
+
The status remains absent from layout and the accessibility tree until it
|
|
86
|
+
is the URL target. */
|
|
87
|
+
.ef-form__outcome { display: none; }
|
|
88
|
+
.ef-form__outcome:target {
|
|
89
|
+
--ef-color-text-secondary: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
90
|
+
--ef-color-text-muted: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
91
|
+
--ef-surface-accent-text-color: var(--ef-color-text-primary, #171a18);
|
|
92
|
+
display: block;
|
|
93
|
+
padding: var(--ef-primitive-spacing-3, 0.75rem);
|
|
94
|
+
border-inline-start: 0.25rem solid var(--ef-color-status-success, #2f6f4e);
|
|
95
|
+
background: var(--ef-color-surface-secondary, #e3e0d7);
|
|
96
|
+
color: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
97
|
+
font-weight: 650;
|
|
98
|
+
}
|
|
99
|
+
|
|
67
100
|
.ef-field > :is(input[type="date"], input[type="time"], input[type="datetime-local"]) {
|
|
68
101
|
min-inline-size: 0;
|
|
69
102
|
inline-size: 100%;
|
|
@@ -5428,4 +5461,3 @@
|
|
|
5428
5461
|
.ef-icon { color: CanvasText; }
|
|
5429
5462
|
}
|
|
5430
5463
|
}
|
|
5431
|
-
|
package/dist/foundations.css
CHANGED
|
@@ -96,6 +96,12 @@
|
|
|
96
96
|
transition-duration: var(--ef-motion-direct-duration, 0ms);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
:where(button, .ef-button):disabled {
|
|
100
|
+
border-style: dashed;
|
|
101
|
+
cursor: not-allowed;
|
|
102
|
+
opacity: 0.62;
|
|
103
|
+
}
|
|
104
|
+
|
|
99
105
|
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) {
|
|
100
106
|
box-sizing: border-box;
|
|
101
107
|
min-block-size: 2.75rem;
|
|
@@ -151,6 +157,28 @@
|
|
|
151
157
|
text-align: start;
|
|
152
158
|
}
|
|
153
159
|
|
|
160
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):disabled {
|
|
161
|
+
--ef-color-text-secondary: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
162
|
+
--ef-color-text-muted: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
163
|
+
--ef-surface-accent-text-color: var(--ef-color-text-primary, #171a18);
|
|
164
|
+
border-style: dashed;
|
|
165
|
+
background: var(--ef-color-surface-secondary, #e3e0d7);
|
|
166
|
+
cursor: not-allowed;
|
|
167
|
+
opacity: 0.62;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea):read-only:not(:disabled) {
|
|
171
|
+
border-style: dashed;
|
|
172
|
+
background: color-mix(in srgb, var(--ef-color-surface-secondary, #e3e0d7) 55%, transparent);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* Invalid state keeps native semantics and adds a shape cue. The associated
|
|
176
|
+
recovery message remains the non-colour explanation of what to fix. */
|
|
177
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):where([aria-invalid="true"], :user-invalid) {
|
|
178
|
+
border-inline-start-width: 0.3rem;
|
|
179
|
+
border-inline-start-color: var(--ef-color-status-danger, #8d3027);
|
|
180
|
+
}
|
|
181
|
+
|
|
154
182
|
:where(:focus-visible) {
|
|
155
183
|
outline: 3px solid var(--ef-color-focus-gap, #f2efe7);
|
|
156
184
|
outline-offset: 2px;
|
package/dist/icons/registry.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Forma 0.
|
|
1
|
+
/*! Forma 0.8.0 | forma-all.css | bundle echelon-marketing
|
|
2
2
|
Complete Forma surface (application components, assessment, and marketing layers) for sites that also present Forma application patterns such as data grids or status lozenges.
|
|
3
3
|
Generated by tools/PresentationBundler. Do not edit; pin by version and sha256. */
|
|
4
4
|
|
|
@@ -636,6 +636,12 @@
|
|
|
636
636
|
transition-duration: var(--ef-motion-direct-duration, 0ms);
|
|
637
637
|
}
|
|
638
638
|
|
|
639
|
+
:where(button, .ef-button):disabled {
|
|
640
|
+
border-style: dashed;
|
|
641
|
+
cursor: not-allowed;
|
|
642
|
+
opacity: 0.62;
|
|
643
|
+
}
|
|
644
|
+
|
|
639
645
|
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) {
|
|
640
646
|
box-sizing: border-box;
|
|
641
647
|
min-block-size: 2.75rem;
|
|
@@ -691,6 +697,28 @@
|
|
|
691
697
|
text-align: start;
|
|
692
698
|
}
|
|
693
699
|
|
|
700
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):disabled {
|
|
701
|
+
--ef-color-text-secondary: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
702
|
+
--ef-color-text-muted: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
703
|
+
--ef-surface-accent-text-color: var(--ef-color-text-primary, #171a18);
|
|
704
|
+
border-style: dashed;
|
|
705
|
+
background: var(--ef-color-surface-secondary, #e3e0d7);
|
|
706
|
+
cursor: not-allowed;
|
|
707
|
+
opacity: 0.62;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea):read-only:not(:disabled) {
|
|
711
|
+
border-style: dashed;
|
|
712
|
+
background: color-mix(in srgb, var(--ef-color-surface-secondary, #e3e0d7) 55%, transparent);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/* Invalid state keeps native semantics and adds a shape cue. The associated
|
|
716
|
+
recovery message remains the non-colour explanation of what to fix. */
|
|
717
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):where([aria-invalid="true"], :user-invalid) {
|
|
718
|
+
border-inline-start-width: 0.3rem;
|
|
719
|
+
border-inline-start-color: var(--ef-color-status-danger, #8d3027);
|
|
720
|
+
}
|
|
721
|
+
|
|
694
722
|
:where(:focus-visible) {
|
|
695
723
|
outline: 3px solid var(--ef-color-focus-gap, #f2efe7);
|
|
696
724
|
outline-offset: 2px;
|
|
@@ -875,6 +903,39 @@
|
|
|
875
903
|
.ef-form-row > .ef-field > :not(.ef-field__label, .ef-field__description, .ef-validation-message) { grid-row: 3; margin-block-start: var(--ef-primitive-spacing-2, 0.5rem); }
|
|
876
904
|
.ef-form-row > .ef-field > .ef-validation-message { grid-row: 4; margin-block-start: var(--ef-primitive-spacing-2, 0.5rem); }
|
|
877
905
|
|
|
906
|
+
/* Form contract ------------------------------------------------------- */
|
|
907
|
+
.ef-form {
|
|
908
|
+
container-type: inline-size;
|
|
909
|
+
display: grid;
|
|
910
|
+
gap: var(--ef-form-gap, var(--ef-primitive-spacing-5, 1.5rem));
|
|
911
|
+
min-inline-size: 0;
|
|
912
|
+
max-inline-size: var(--ef-form-max, 64rem);
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
.ef-form > :where(h1, h2, h3, p) { margin-block: 0; }
|
|
916
|
+
|
|
917
|
+
/* Native constraint validation owns validity. The recovery text is in the
|
|
918
|
+
DOM and programmatically associated from first render, but appears only
|
|
919
|
+
after the browser marks the control user-invalid. */
|
|
920
|
+
.ef-validation-message--when-invalid { display: none; }
|
|
921
|
+
.ef-field:has(> :user-invalid) > .ef-validation-message--when-invalid { display: flex; }
|
|
922
|
+
|
|
923
|
+
/* GET submission to the declared fragment is a real, script-free outcome.
|
|
924
|
+
The status remains absent from layout and the accessibility tree until it
|
|
925
|
+
is the URL target. */
|
|
926
|
+
.ef-form__outcome { display: none; }
|
|
927
|
+
.ef-form__outcome:target {
|
|
928
|
+
--ef-color-text-secondary: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
929
|
+
--ef-color-text-muted: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
930
|
+
--ef-surface-accent-text-color: var(--ef-color-text-primary, #171a18);
|
|
931
|
+
display: block;
|
|
932
|
+
padding: var(--ef-primitive-spacing-3, 0.75rem);
|
|
933
|
+
border-inline-start: 0.25rem solid var(--ef-color-status-success, #2f6f4e);
|
|
934
|
+
background: var(--ef-color-surface-secondary, #e3e0d7);
|
|
935
|
+
color: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
936
|
+
font-weight: 650;
|
|
937
|
+
}
|
|
938
|
+
|
|
878
939
|
.ef-field > :is(input[type="date"], input[type="time"], input[type="datetime-local"]) {
|
|
879
940
|
min-inline-size: 0;
|
|
880
941
|
inline-size: 100%;
|
|
@@ -6240,7 +6301,6 @@
|
|
|
6240
6301
|
}
|
|
6241
6302
|
}
|
|
6242
6303
|
|
|
6243
|
-
|
|
6244
6304
|
@layer echelon.assessment {
|
|
6245
6305
|
/* Question shell ------------------------------------------------------ */
|
|
6246
6306
|
.ef-question {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Forma 0.
|
|
1
|
+
/*! Forma 0.8.0 | forma-echelon-marketing.css | bundle echelon-marketing
|
|
2
2
|
Single-file Echelon marketing presentation: forma-marketing.css followed by the Echelon theme. Most sites load only this file.
|
|
3
3
|
Generated by tools/PresentationBundler. Do not edit; pin by version and sha256. */
|
|
4
4
|
|
|
@@ -736,6 +736,12 @@
|
|
|
736
736
|
transition-duration: var(--ef-motion-direct-duration, 0ms);
|
|
737
737
|
}
|
|
738
738
|
|
|
739
|
+
:where(button, .ef-button):disabled {
|
|
740
|
+
border-style: dashed;
|
|
741
|
+
cursor: not-allowed;
|
|
742
|
+
opacity: 0.62;
|
|
743
|
+
}
|
|
744
|
+
|
|
739
745
|
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) {
|
|
740
746
|
box-sizing: border-box;
|
|
741
747
|
min-block-size: 2.75rem;
|
|
@@ -791,6 +797,28 @@
|
|
|
791
797
|
text-align: start;
|
|
792
798
|
}
|
|
793
799
|
|
|
800
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):disabled {
|
|
801
|
+
--ef-color-text-secondary: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
802
|
+
--ef-color-text-muted: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
803
|
+
--ef-surface-accent-text-color: var(--ef-color-text-primary, #171a18);
|
|
804
|
+
border-style: dashed;
|
|
805
|
+
background: var(--ef-color-surface-secondary, #e3e0d7);
|
|
806
|
+
cursor: not-allowed;
|
|
807
|
+
opacity: 0.62;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea):read-only:not(:disabled) {
|
|
811
|
+
border-style: dashed;
|
|
812
|
+
background: color-mix(in srgb, var(--ef-color-surface-secondary, #e3e0d7) 55%, transparent);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/* Invalid state keeps native semantics and adds a shape cue. The associated
|
|
816
|
+
recovery message remains the non-colour explanation of what to fix. */
|
|
817
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):where([aria-invalid="true"], :user-invalid) {
|
|
818
|
+
border-inline-start-width: 0.3rem;
|
|
819
|
+
border-inline-start-color: var(--ef-color-status-danger, #8d3027);
|
|
820
|
+
}
|
|
821
|
+
|
|
794
822
|
:where(:focus-visible) {
|
|
795
823
|
outline: 3px solid var(--ef-color-focus-gap, #f2efe7);
|
|
796
824
|
outline-offset: 2px;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Forma 0.
|
|
1
|
+
/*! Forma 0.8.0 | forma-marketing-theme-echelon.css | bundle echelon-marketing
|
|
2
2
|
Echelon Marketing Theme: compiled theme tokens and theme hooks. Load after forma-marketing.css.
|
|
3
3
|
Generated by tools/PresentationBundler. Do not edit; pin by version and sha256. */
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Forma 0.
|
|
1
|
+
/*! Forma 0.8.0 | forma-marketing.css | bundle echelon-marketing
|
|
2
2
|
Brand-neutral marketing layer: core tokens, role defaults, Forma foundations, marketing foundations, components, and layouts.
|
|
3
3
|
Generated by tools/PresentationBundler. Do not edit; pin by version and sha256. */
|
|
4
4
|
|
|
@@ -735,6 +735,12 @@
|
|
|
735
735
|
transition-duration: var(--ef-motion-direct-duration, 0ms);
|
|
736
736
|
}
|
|
737
737
|
|
|
738
|
+
:where(button, .ef-button):disabled {
|
|
739
|
+
border-style: dashed;
|
|
740
|
+
cursor: not-allowed;
|
|
741
|
+
opacity: 0.62;
|
|
742
|
+
}
|
|
743
|
+
|
|
738
744
|
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) {
|
|
739
745
|
box-sizing: border-box;
|
|
740
746
|
min-block-size: 2.75rem;
|
|
@@ -790,6 +796,28 @@
|
|
|
790
796
|
text-align: start;
|
|
791
797
|
}
|
|
792
798
|
|
|
799
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):disabled {
|
|
800
|
+
--ef-color-text-secondary: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
801
|
+
--ef-color-text-muted: var(--ef-color-text-on-secondary-surface, #3a403c);
|
|
802
|
+
--ef-surface-accent-text-color: var(--ef-color-text-primary, #171a18);
|
|
803
|
+
border-style: dashed;
|
|
804
|
+
background: var(--ef-color-surface-secondary, #e3e0d7);
|
|
805
|
+
cursor: not-allowed;
|
|
806
|
+
opacity: 0.62;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea):read-only:not(:disabled) {
|
|
810
|
+
border-style: dashed;
|
|
811
|
+
background: color-mix(in srgb, var(--ef-color-surface-secondary, #e3e0d7) 55%, transparent);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
/* Invalid state keeps native semantics and adds a shape cue. The associated
|
|
815
|
+
recovery message remains the non-colour explanation of what to fix. */
|
|
816
|
+
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select):where([aria-invalid="true"], :user-invalid) {
|
|
817
|
+
border-inline-start-width: 0.3rem;
|
|
818
|
+
border-inline-start-color: var(--ef-color-status-danger, #8d3027);
|
|
819
|
+
}
|
|
820
|
+
|
|
793
821
|
:where(:focus-visible) {
|
|
794
822
|
outline: 3px solid var(--ef-color-focus-gap, #f2efe7);
|
|
795
823
|
outline-offset: 2px;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"forma": "0.
|
|
3
|
+
"forma": "0.8.0",
|
|
4
4
|
"bundle": "echelon-marketing",
|
|
5
5
|
"description": "Forma presentation artifacts for Echelon marketing sites. Every artifact is a single self-contained CSS file with no imports or relative URLs.",
|
|
6
|
-
"releaseTag": "v0.
|
|
6
|
+
"releaseTag": "v0.8.0",
|
|
7
7
|
"artifacts": [
|
|
8
8
|
{
|
|
9
9
|
"file": "forma-marketing.css",
|
|
10
10
|
"description": "Brand-neutral marketing layer: core tokens, role defaults, Forma foundations, marketing foundations, components, and layouts.",
|
|
11
|
-
"bytes":
|
|
12
|
-
"sha256": "
|
|
11
|
+
"bytes": 82968,
|
|
12
|
+
"sha256": "3089398445d5898cdae9cc0dc2ec4629e8130a1a885291d9ae1bfdf9141dab48",
|
|
13
13
|
"sources": [
|
|
14
14
|
"dist/tokens.css",
|
|
15
15
|
"src/marketing/roles.css",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"file": "forma-marketing-theme-echelon.css",
|
|
24
24
|
"description": "Echelon Marketing Theme: compiled theme tokens and theme hooks. Load after forma-marketing.css.",
|
|
25
25
|
"bytes": 6295,
|
|
26
|
-
"sha256": "
|
|
26
|
+
"sha256": "970b7986b609331c1bc12d51173c8e185f48906df5d8b2fcc585c3187be3e9fd",
|
|
27
27
|
"sources": [
|
|
28
28
|
"build/marketing/echelon-marketing.tokens.css",
|
|
29
29
|
"themes/echelon/marketing.css"
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
{
|
|
33
33
|
"file": "forma-echelon-marketing.css",
|
|
34
34
|
"description": "Single-file Echelon marketing presentation: forma-marketing.css followed by the Echelon theme. Most sites load only this file.",
|
|
35
|
-
"bytes":
|
|
36
|
-
"sha256": "
|
|
35
|
+
"bytes": 89108,
|
|
36
|
+
"sha256": "ee17288af3ae5ba708b8fd1b471835a14ea93da588a39206dcc27db2ee2f98ba",
|
|
37
37
|
"sources": [
|
|
38
38
|
"artifact:forma-marketing.css",
|
|
39
39
|
"artifact:forma-marketing-theme-echelon.css"
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
{
|
|
43
43
|
"file": "forma-all.css",
|
|
44
44
|
"description": "Complete Forma surface (application components, assessment, and marketing layers) for sites that also present Forma application patterns such as data grids or status lozenges.",
|
|
45
|
-
"bytes":
|
|
46
|
-
"sha256": "
|
|
45
|
+
"bytes": 330018,
|
|
46
|
+
"sha256": "93cafe35f219e7297b8ad5cd8b3a22ad660e753a2ce247c0709eb75281701cad",
|
|
47
47
|
"sources": [
|
|
48
48
|
"dist/all.css"
|
|
49
49
|
]
|