@echelon-foundry/design-system 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/dist/all.css +268 -74
- package/dist/assessment.css +13 -2
- package/dist/build-metrics.json +7 -5
- package/dist/components.css +175 -69
- package/dist/foundations.css +60 -2
- package/dist/icons/registry.json +1 -1
- package/dist/marketing/forma-all.css +269 -75
- package/dist/marketing/forma-echelon-marketing.css +81 -4
- package/dist/marketing/forma-marketing-theme-echelon.css +1 -1
- package/dist/marketing/forma-marketing.css +81 -4
- package/dist/marketing/forma-marketing.manifest.json +9 -9
- package/dist/marketing/forma-marketing.sha256 +4 -4
- package/dist/marketing.css +20 -1
- package/dist/patterns/form-row.html +15 -0
- package/figma/component-contracts.json +10 -0
- package/package.json +4 -3
- package/patterns/form-row.html +15 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Forma 0.
|
|
1
|
+
/*! Forma 0.7.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
|
|
|
@@ -737,6 +737,7 @@
|
|
|
737
737
|
}
|
|
738
738
|
|
|
739
739
|
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) {
|
|
740
|
+
box-sizing: border-box;
|
|
740
741
|
min-block-size: 2.75rem;
|
|
741
742
|
inline-size: 100%;
|
|
742
743
|
padding: 0.7rem 0.8rem;
|
|
@@ -744,6 +745,50 @@
|
|
|
744
745
|
border-radius: var(--ef-primitive-radius-none, 0);
|
|
745
746
|
background: var(--ef-color-surface-primary, #f2efe7);
|
|
746
747
|
color: var(--ef-color-text-primary, #171a18);
|
|
748
|
+
font: inherit;
|
|
749
|
+
line-height: var(--ef-field-line-height, 1.6);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/*
|
|
753
|
+
* Equivalent single-line controls share one intrinsic block size
|
|
754
|
+
* (UI-LAYOUT-INTERACTION ULI-L02, L13): one line of field text plus the
|
|
755
|
+
* field padding and border. Native date/time and select boxes otherwise
|
|
756
|
+
* differ by several pixels from text inputs (Chromium: 51.97 vs 49.97 vs
|
|
757
|
+
* 46.38 px), which staggers peers in a row. Em-based, so it grows with
|
|
758
|
+
* the user's text size.
|
|
759
|
+
*/
|
|
760
|
+
:where(
|
|
761
|
+
input:not([type]),
|
|
762
|
+
input:is([type="text"], [type="email"], [type="password"], [type="search"], [type="tel"], [type="url"], [type="number"],
|
|
763
|
+
[type="date"], [type="time"], [type="datetime-local"], [type="month"], [type="week"]),
|
|
764
|
+
select:not([multiple], [size])
|
|
765
|
+
) {
|
|
766
|
+
block-size: var(--ef-field-control-block-size, calc(var(--ef-field-line-height, 1.6) * 1em + 1.4rem + 2px));
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
:where(input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"], input[type="week"])::-webkit-datetime-edit {
|
|
770
|
+
padding-block: 0;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/* A fieldset's default min-inline-size is min-content, which lets a long
|
|
774
|
+
legend or option widen a form past a narrow viewport (ULI-L05). */
|
|
775
|
+
:where(fieldset) {
|
|
776
|
+
min-inline-size: 0;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
/* iOS temporal controls otherwise retain a native intrinsic width despite
|
|
780
|
+
the author's width limit. Keep the native picker, not its native box. */
|
|
781
|
+
:where(input[type="date"], input[type="time"], input[type="datetime-local"]) {
|
|
782
|
+
-webkit-appearance: none;
|
|
783
|
+
appearance: none;
|
|
784
|
+
box-sizing: border-box;
|
|
785
|
+
min-inline-size: 0;
|
|
786
|
+
max-inline-size: 100%;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
:where(input[type="date"], input[type="time"], input[type="datetime-local"])::-webkit-date-and-time-value {
|
|
790
|
+
min-inline-size: 0;
|
|
791
|
+
text-align: start;
|
|
747
792
|
}
|
|
748
793
|
|
|
749
794
|
:where(:focus-visible) {
|
|
@@ -755,16 +800,29 @@
|
|
|
755
800
|
.ef-stack { display: flex; flex-direction: column; gap: var(--ef-stack-gap, var(--ef-primitive-spacing-4, 1rem)); }
|
|
756
801
|
.ef-cluster { display: flex; flex-wrap: wrap; gap: var(--ef-cluster-gap, var(--ef-primitive-spacing-3, 0.75rem)); align-items: center; }
|
|
757
802
|
/* .ef-actions (catalog: button) is an application-layer row of related actions; it was styled only in marketing.css (forma#93 gap). */
|
|
758
|
-
|
|
803
|
+
/* min-inline-size: 0 lets an action row shrink inside a flex or grid parent
|
|
804
|
+
instead of being held at its widest button's word (ULI-L05). */
|
|
805
|
+
.ef-actions { display: flex; flex-wrap: wrap; gap: var(--ef-primitive-spacing-3, 0.75rem); align-items: center; min-inline-size: 0; }
|
|
759
806
|
.ef-grid { display: grid; gap: var(--ef-grid-gap, var(--ef-primitive-spacing-4, 1rem)); grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--ef-grid-min, 16rem)), 1fr)); }
|
|
760
807
|
.ef-section { padding-block: var(--ef-section-space, var(--ef-primitive-spacing-7, 3rem)); }
|
|
761
808
|
.ef-surface { --ef-color-text-secondary: var(--ef-color-text-on-secondary-surface, #3a403c); --ef-color-text-muted: var(--ef-color-text-on-secondary-surface, #3a403c); --ef-surface-accent-text-color: var(--ef-color-text-primary, #171a18); min-inline-size: 0; padding: var(--ef-surface-space, var(--ef-primitive-spacing-5, 1.5rem)); background: var(--ef-color-surface-secondary, #e3e0d7); color: var(--ef-color-text-on-secondary-surface, #3a403c); border: 1px solid var(--ef-color-border-subtle, #e3e0d7); }
|
|
762
809
|
.ef-surface :where(h1, h2, h3, h4, h5, h6, p) { color: inherit; }
|
|
763
810
|
|
|
764
|
-
:where(h1, h2, h3, h4, h5, h6, p, a, label, legend, td, th) {
|
|
811
|
+
:where(h1, h2, h3, h4, h5, h6, p, a, label, legend, td, th, dt, dd, caption, figcaption) {
|
|
765
812
|
overflow-wrap: anywhere;
|
|
766
813
|
}
|
|
767
814
|
|
|
815
|
+
/* Action labels never split mid-word because their container allows it
|
|
816
|
+
(a link button inherits the rule above; a button inherits it from a
|
|
817
|
+
table cell). A single word wider than its container may still break
|
|
818
|
+
rather than overflow. Must follow the rule above (ULI-L06, L07). The
|
|
819
|
+
inline-size cap also clamps a flex item's automatic minimum, so a
|
|
820
|
+
button never pushes its row past its container (ULI-L05). */
|
|
821
|
+
:where(button, .ef-button) {
|
|
822
|
+
overflow-wrap: break-word;
|
|
823
|
+
max-inline-size: 100%;
|
|
824
|
+
}
|
|
825
|
+
|
|
768
826
|
@media (prefers-reduced-motion: reduce) {
|
|
769
827
|
*, *::before, *::after {
|
|
770
828
|
scroll-behavior: auto !important;
|
|
@@ -1261,6 +1319,9 @@
|
|
|
1261
1319
|
flex-wrap: wrap;
|
|
1262
1320
|
align-items: center;
|
|
1263
1321
|
gap: var(--ef-space-3);
|
|
1322
|
+
/* Shrinks inside a flex or grid parent instead of being held at its
|
|
1323
|
+
widest button's word (ULI-L05). */
|
|
1324
|
+
min-inline-size: 0;
|
|
1264
1325
|
}
|
|
1265
1326
|
|
|
1266
1327
|
.ef-site .ef-button {
|
|
@@ -1280,6 +1341,10 @@
|
|
|
1280
1341
|
line-height: var(--ef-type-leading-snug);
|
|
1281
1342
|
text-align: center;
|
|
1282
1343
|
text-decoration: none;
|
|
1344
|
+
/* Never wider than its row and never split mid-word unless one word is
|
|
1345
|
+
wider than the row (ULI-L05, L06). */
|
|
1346
|
+
max-inline-size: 100%;
|
|
1347
|
+
overflow-wrap: break-word;
|
|
1283
1348
|
cursor: pointer;
|
|
1284
1349
|
/* Hover and press are perceptual emphasis on the surface only: the hit
|
|
1285
1350
|
target never moves under the pointer (MOT-014). */
|
|
@@ -1526,7 +1591,10 @@
|
|
|
1526
1591
|
min-block-size: 1.5rem;
|
|
1527
1592
|
font-size: var(--ef-type-size-small);
|
|
1528
1593
|
font-weight: var(--ef-type-weight-strong);
|
|
1529
|
-
|
|
1594
|
+
/* One line whenever it fits (inline-flex shrinks to its content); it
|
|
1595
|
+
wraps at word boundaries instead of overflowing a narrow column at
|
|
1596
|
+
large text sizes (UI-LAYOUT-INTERACTION ULI-L05). */
|
|
1597
|
+
max-inline-size: 100%;
|
|
1530
1598
|
}
|
|
1531
1599
|
|
|
1532
1600
|
/* Four disparate columns cannot degrade by a minimum item size, so the
|
|
@@ -1558,6 +1626,9 @@
|
|
|
1558
1626
|
padding-block: var(--ef-space-4);
|
|
1559
1627
|
border-block-end: var(--ef-shape-border-width) solid var(--ef-tone-rule);
|
|
1560
1628
|
color: var(--ef-tone-text);
|
|
1629
|
+
/* The step text is an anonymous flex item; let a long word wrap inside
|
|
1630
|
+
it instead of overflowing a narrow column (ULI-L05). */
|
|
1631
|
+
overflow-wrap: anywhere;
|
|
1561
1632
|
}
|
|
1562
1633
|
|
|
1563
1634
|
.ef-steps > li::before {
|
|
@@ -1687,6 +1758,7 @@
|
|
|
1687
1758
|
|
|
1688
1759
|
.ef-code-figure > figcaption {
|
|
1689
1760
|
margin-block-end: var(--ef-space-2);
|
|
1761
|
+
overflow-wrap: anywhere;
|
|
1690
1762
|
color: var(--ef-tone-muted);
|
|
1691
1763
|
font-family: var(--ef-type-family-mono);
|
|
1692
1764
|
font-size: var(--ef-type-size-label);
|
|
@@ -1828,6 +1900,11 @@
|
|
|
1828
1900
|
.ef-site .ef-section[data-ef-tone]:not([data-ef-tone="page"]) {
|
|
1829
1901
|
margin-block: calc(var(--ef-layout-section-space) / 2);
|
|
1830
1902
|
padding: calc(var(--ef-layout-block-space) * 2);
|
|
1903
|
+
/* The block-space token is rem-based; at enlarged text on a phone it
|
|
1904
|
+
would leave a few characters of line length (96px content at 320px
|
|
1905
|
+
and 200% text). Cap only the inline padding by viewport width; this
|
|
1906
|
+
changes nothing at the default text size (ULI-L05). */
|
|
1907
|
+
padding-inline: min(calc(var(--ef-layout-block-space) * 2), 12.5vw);
|
|
1831
1908
|
}
|
|
1832
1909
|
|
|
1833
1910
|
.ef-section > * + * { margin-block-start: var(--ef-layout-stack-space); }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Forma 0.
|
|
1
|
+
/*! Forma 0.7.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.7.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
|
|
|
@@ -736,6 +736,7 @@
|
|
|
736
736
|
}
|
|
737
737
|
|
|
738
738
|
:where(input:not([type="checkbox"], [type="radio"], [type="range"]), textarea, select) {
|
|
739
|
+
box-sizing: border-box;
|
|
739
740
|
min-block-size: 2.75rem;
|
|
740
741
|
inline-size: 100%;
|
|
741
742
|
padding: 0.7rem 0.8rem;
|
|
@@ -743,6 +744,50 @@
|
|
|
743
744
|
border-radius: var(--ef-primitive-radius-none, 0);
|
|
744
745
|
background: var(--ef-color-surface-primary, #f2efe7);
|
|
745
746
|
color: var(--ef-color-text-primary, #171a18);
|
|
747
|
+
font: inherit;
|
|
748
|
+
line-height: var(--ef-field-line-height, 1.6);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/*
|
|
752
|
+
* Equivalent single-line controls share one intrinsic block size
|
|
753
|
+
* (UI-LAYOUT-INTERACTION ULI-L02, L13): one line of field text plus the
|
|
754
|
+
* field padding and border. Native date/time and select boxes otherwise
|
|
755
|
+
* differ by several pixels from text inputs (Chromium: 51.97 vs 49.97 vs
|
|
756
|
+
* 46.38 px), which staggers peers in a row. Em-based, so it grows with
|
|
757
|
+
* the user's text size.
|
|
758
|
+
*/
|
|
759
|
+
:where(
|
|
760
|
+
input:not([type]),
|
|
761
|
+
input:is([type="text"], [type="email"], [type="password"], [type="search"], [type="tel"], [type="url"], [type="number"],
|
|
762
|
+
[type="date"], [type="time"], [type="datetime-local"], [type="month"], [type="week"]),
|
|
763
|
+
select:not([multiple], [size])
|
|
764
|
+
) {
|
|
765
|
+
block-size: var(--ef-field-control-block-size, calc(var(--ef-field-line-height, 1.6) * 1em + 1.4rem + 2px));
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
:where(input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"], input[type="week"])::-webkit-datetime-edit {
|
|
769
|
+
padding-block: 0;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/* A fieldset's default min-inline-size is min-content, which lets a long
|
|
773
|
+
legend or option widen a form past a narrow viewport (ULI-L05). */
|
|
774
|
+
:where(fieldset) {
|
|
775
|
+
min-inline-size: 0;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/* iOS temporal controls otherwise retain a native intrinsic width despite
|
|
779
|
+
the author's width limit. Keep the native picker, not its native box. */
|
|
780
|
+
:where(input[type="date"], input[type="time"], input[type="datetime-local"]) {
|
|
781
|
+
-webkit-appearance: none;
|
|
782
|
+
appearance: none;
|
|
783
|
+
box-sizing: border-box;
|
|
784
|
+
min-inline-size: 0;
|
|
785
|
+
max-inline-size: 100%;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
:where(input[type="date"], input[type="time"], input[type="datetime-local"])::-webkit-date-and-time-value {
|
|
789
|
+
min-inline-size: 0;
|
|
790
|
+
text-align: start;
|
|
746
791
|
}
|
|
747
792
|
|
|
748
793
|
:where(:focus-visible) {
|
|
@@ -754,16 +799,29 @@
|
|
|
754
799
|
.ef-stack { display: flex; flex-direction: column; gap: var(--ef-stack-gap, var(--ef-primitive-spacing-4, 1rem)); }
|
|
755
800
|
.ef-cluster { display: flex; flex-wrap: wrap; gap: var(--ef-cluster-gap, var(--ef-primitive-spacing-3, 0.75rem)); align-items: center; }
|
|
756
801
|
/* .ef-actions (catalog: button) is an application-layer row of related actions; it was styled only in marketing.css (forma#93 gap). */
|
|
757
|
-
|
|
802
|
+
/* min-inline-size: 0 lets an action row shrink inside a flex or grid parent
|
|
803
|
+
instead of being held at its widest button's word (ULI-L05). */
|
|
804
|
+
.ef-actions { display: flex; flex-wrap: wrap; gap: var(--ef-primitive-spacing-3, 0.75rem); align-items: center; min-inline-size: 0; }
|
|
758
805
|
.ef-grid { display: grid; gap: var(--ef-grid-gap, var(--ef-primitive-spacing-4, 1rem)); grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--ef-grid-min, 16rem)), 1fr)); }
|
|
759
806
|
.ef-section { padding-block: var(--ef-section-space, var(--ef-primitive-spacing-7, 3rem)); }
|
|
760
807
|
.ef-surface { --ef-color-text-secondary: var(--ef-color-text-on-secondary-surface, #3a403c); --ef-color-text-muted: var(--ef-color-text-on-secondary-surface, #3a403c); --ef-surface-accent-text-color: var(--ef-color-text-primary, #171a18); min-inline-size: 0; padding: var(--ef-surface-space, var(--ef-primitive-spacing-5, 1.5rem)); background: var(--ef-color-surface-secondary, #e3e0d7); color: var(--ef-color-text-on-secondary-surface, #3a403c); border: 1px solid var(--ef-color-border-subtle, #e3e0d7); }
|
|
761
808
|
.ef-surface :where(h1, h2, h3, h4, h5, h6, p) { color: inherit; }
|
|
762
809
|
|
|
763
|
-
:where(h1, h2, h3, h4, h5, h6, p, a, label, legend, td, th) {
|
|
810
|
+
:where(h1, h2, h3, h4, h5, h6, p, a, label, legend, td, th, dt, dd, caption, figcaption) {
|
|
764
811
|
overflow-wrap: anywhere;
|
|
765
812
|
}
|
|
766
813
|
|
|
814
|
+
/* Action labels never split mid-word because their container allows it
|
|
815
|
+
(a link button inherits the rule above; a button inherits it from a
|
|
816
|
+
table cell). A single word wider than its container may still break
|
|
817
|
+
rather than overflow. Must follow the rule above (ULI-L06, L07). The
|
|
818
|
+
inline-size cap also clamps a flex item's automatic minimum, so a
|
|
819
|
+
button never pushes its row past its container (ULI-L05). */
|
|
820
|
+
:where(button, .ef-button) {
|
|
821
|
+
overflow-wrap: break-word;
|
|
822
|
+
max-inline-size: 100%;
|
|
823
|
+
}
|
|
824
|
+
|
|
767
825
|
@media (prefers-reduced-motion: reduce) {
|
|
768
826
|
*, *::before, *::after {
|
|
769
827
|
scroll-behavior: auto !important;
|
|
@@ -1260,6 +1318,9 @@
|
|
|
1260
1318
|
flex-wrap: wrap;
|
|
1261
1319
|
align-items: center;
|
|
1262
1320
|
gap: var(--ef-space-3);
|
|
1321
|
+
/* Shrinks inside a flex or grid parent instead of being held at its
|
|
1322
|
+
widest button's word (ULI-L05). */
|
|
1323
|
+
min-inline-size: 0;
|
|
1263
1324
|
}
|
|
1264
1325
|
|
|
1265
1326
|
.ef-site .ef-button {
|
|
@@ -1279,6 +1340,10 @@
|
|
|
1279
1340
|
line-height: var(--ef-type-leading-snug);
|
|
1280
1341
|
text-align: center;
|
|
1281
1342
|
text-decoration: none;
|
|
1343
|
+
/* Never wider than its row and never split mid-word unless one word is
|
|
1344
|
+
wider than the row (ULI-L05, L06). */
|
|
1345
|
+
max-inline-size: 100%;
|
|
1346
|
+
overflow-wrap: break-word;
|
|
1282
1347
|
cursor: pointer;
|
|
1283
1348
|
/* Hover and press are perceptual emphasis on the surface only: the hit
|
|
1284
1349
|
target never moves under the pointer (MOT-014). */
|
|
@@ -1525,7 +1590,10 @@
|
|
|
1525
1590
|
min-block-size: 1.5rem;
|
|
1526
1591
|
font-size: var(--ef-type-size-small);
|
|
1527
1592
|
font-weight: var(--ef-type-weight-strong);
|
|
1528
|
-
|
|
1593
|
+
/* One line whenever it fits (inline-flex shrinks to its content); it
|
|
1594
|
+
wraps at word boundaries instead of overflowing a narrow column at
|
|
1595
|
+
large text sizes (UI-LAYOUT-INTERACTION ULI-L05). */
|
|
1596
|
+
max-inline-size: 100%;
|
|
1529
1597
|
}
|
|
1530
1598
|
|
|
1531
1599
|
/* Four disparate columns cannot degrade by a minimum item size, so the
|
|
@@ -1557,6 +1625,9 @@
|
|
|
1557
1625
|
padding-block: var(--ef-space-4);
|
|
1558
1626
|
border-block-end: var(--ef-shape-border-width) solid var(--ef-tone-rule);
|
|
1559
1627
|
color: var(--ef-tone-text);
|
|
1628
|
+
/* The step text is an anonymous flex item; let a long word wrap inside
|
|
1629
|
+
it instead of overflowing a narrow column (ULI-L05). */
|
|
1630
|
+
overflow-wrap: anywhere;
|
|
1560
1631
|
}
|
|
1561
1632
|
|
|
1562
1633
|
.ef-steps > li::before {
|
|
@@ -1686,6 +1757,7 @@
|
|
|
1686
1757
|
|
|
1687
1758
|
.ef-code-figure > figcaption {
|
|
1688
1759
|
margin-block-end: var(--ef-space-2);
|
|
1760
|
+
overflow-wrap: anywhere;
|
|
1689
1761
|
color: var(--ef-tone-muted);
|
|
1690
1762
|
font-family: var(--ef-type-family-mono);
|
|
1691
1763
|
font-size: var(--ef-type-size-label);
|
|
@@ -1827,6 +1899,11 @@
|
|
|
1827
1899
|
.ef-site .ef-section[data-ef-tone]:not([data-ef-tone="page"]) {
|
|
1828
1900
|
margin-block: calc(var(--ef-layout-section-space) / 2);
|
|
1829
1901
|
padding: calc(var(--ef-layout-block-space) * 2);
|
|
1902
|
+
/* The block-space token is rem-based; at enlarged text on a phone it
|
|
1903
|
+
would leave a few characters of line length (96px content at 320px
|
|
1904
|
+
and 200% text). Cap only the inline padding by viewport width; this
|
|
1905
|
+
changes nothing at the default text size (ULI-L05). */
|
|
1906
|
+
padding-inline: min(calc(var(--ef-layout-block-space) * 2), 12.5vw);
|
|
1830
1907
|
}
|
|
1831
1908
|
|
|
1832
1909
|
.ef-section > * + * { margin-block-start: var(--ef-layout-stack-space); }
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"forma": "0.
|
|
3
|
+
"forma": "0.7.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.7.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": 81740,
|
|
12
|
+
"sha256": "171d3cb1485da7a9f83f6bdfc80c8043b0d194a32eadc3e0b5e09b12fade2f80",
|
|
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": "027334d7946a3342812dca297967630cb5f5b1e96dd849672c8e146bf257b153",
|
|
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": 87880,
|
|
36
|
+
"sha256": "2baacb6423cc930e15b1da5cbf39289bed5bd3c721e35ef2e97cb73f48c0c0fc",
|
|
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": 327293,
|
|
46
|
+
"sha256": "5aae64c6fa2e8784347b2207fe7324dae2492a5f45f6b134463e243f419b4dec",
|
|
47
47
|
"sources": [
|
|
48
48
|
"dist/all.css"
|
|
49
49
|
]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
171d3cb1485da7a9f83f6bdfc80c8043b0d194a32eadc3e0b5e09b12fade2f80 forma-marketing.css
|
|
2
|
+
027334d7946a3342812dca297967630cb5f5b1e96dd849672c8e146bf257b153 forma-marketing-theme-echelon.css
|
|
3
|
+
2baacb6423cc930e15b1da5cbf39289bed5bd3c721e35ef2e97cb73f48c0c0fc forma-echelon-marketing.css
|
|
4
|
+
5aae64c6fa2e8784347b2207fe7324dae2492a5f45f6b134463e243f419b4dec forma-all.css
|
package/dist/marketing.css
CHANGED
|
@@ -503,6 +503,9 @@
|
|
|
503
503
|
flex-wrap: wrap;
|
|
504
504
|
align-items: center;
|
|
505
505
|
gap: var(--ef-space-3);
|
|
506
|
+
/* Shrinks inside a flex or grid parent instead of being held at its
|
|
507
|
+
widest button's word (ULI-L05). */
|
|
508
|
+
min-inline-size: 0;
|
|
506
509
|
}
|
|
507
510
|
|
|
508
511
|
.ef-site .ef-button {
|
|
@@ -522,6 +525,10 @@
|
|
|
522
525
|
line-height: var(--ef-type-leading-snug);
|
|
523
526
|
text-align: center;
|
|
524
527
|
text-decoration: none;
|
|
528
|
+
/* Never wider than its row and never split mid-word unless one word is
|
|
529
|
+
wider than the row (ULI-L05, L06). */
|
|
530
|
+
max-inline-size: 100%;
|
|
531
|
+
overflow-wrap: break-word;
|
|
525
532
|
cursor: pointer;
|
|
526
533
|
/* Hover and press are perceptual emphasis on the surface only: the hit
|
|
527
534
|
target never moves under the pointer (MOT-014). */
|
|
@@ -768,7 +775,10 @@
|
|
|
768
775
|
min-block-size: 1.5rem;
|
|
769
776
|
font-size: var(--ef-type-size-small);
|
|
770
777
|
font-weight: var(--ef-type-weight-strong);
|
|
771
|
-
|
|
778
|
+
/* One line whenever it fits (inline-flex shrinks to its content); it
|
|
779
|
+
wraps at word boundaries instead of overflowing a narrow column at
|
|
780
|
+
large text sizes (UI-LAYOUT-INTERACTION ULI-L05). */
|
|
781
|
+
max-inline-size: 100%;
|
|
772
782
|
}
|
|
773
783
|
|
|
774
784
|
/* Four disparate columns cannot degrade by a minimum item size, so the
|
|
@@ -800,6 +810,9 @@
|
|
|
800
810
|
padding-block: var(--ef-space-4);
|
|
801
811
|
border-block-end: var(--ef-shape-border-width) solid var(--ef-tone-rule);
|
|
802
812
|
color: var(--ef-tone-text);
|
|
813
|
+
/* The step text is an anonymous flex item; let a long word wrap inside
|
|
814
|
+
it instead of overflowing a narrow column (ULI-L05). */
|
|
815
|
+
overflow-wrap: anywhere;
|
|
803
816
|
}
|
|
804
817
|
|
|
805
818
|
.ef-steps > li::before {
|
|
@@ -929,6 +942,7 @@
|
|
|
929
942
|
|
|
930
943
|
.ef-code-figure > figcaption {
|
|
931
944
|
margin-block-end: var(--ef-space-2);
|
|
945
|
+
overflow-wrap: anywhere;
|
|
932
946
|
color: var(--ef-tone-muted);
|
|
933
947
|
font-family: var(--ef-type-family-mono);
|
|
934
948
|
font-size: var(--ef-type-size-label);
|
|
@@ -1069,6 +1083,11 @@
|
|
|
1069
1083
|
.ef-site .ef-section[data-ef-tone]:not([data-ef-tone="page"]) {
|
|
1070
1084
|
margin-block: calc(var(--ef-layout-section-space) / 2);
|
|
1071
1085
|
padding: calc(var(--ef-layout-block-space) * 2);
|
|
1086
|
+
/* The block-space token is rem-based; at enlarged text on a phone it
|
|
1087
|
+
would leave a few characters of line length (96px content at 320px
|
|
1088
|
+
and 200% text). Cap only the inline padding by viewport width; this
|
|
1089
|
+
changes nothing at the default text size (ULI-L05). */
|
|
1090
|
+
padding-inline: min(calc(var(--ef-layout-block-space) * 2), 12.5vw);
|
|
1072
1091
|
}
|
|
1073
1092
|
|
|
1074
1093
|
.ef-section > * + * { margin-block-start: var(--ef-layout-stack-space); }
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<div class="ef-form-row">
|
|
2
|
+
<div class="ef-field">
|
|
3
|
+
<label class="ef-field__label" for="form-row-given-name">Given name</label>
|
|
4
|
+
<input id="form-row-given-name" name="given-name" type="text" autocomplete="given-name">
|
|
5
|
+
</div>
|
|
6
|
+
<div class="ef-field">
|
|
7
|
+
<label class="ef-field__label" for="form-row-family-name">Family name</label>
|
|
8
|
+
<span class="ef-field__description" id="form-row-family-name-description">As printed on your passport or national identity card.</span>
|
|
9
|
+
<input id="form-row-family-name" name="family-name" type="text" autocomplete="family-name" aria-describedby="form-row-family-name-description">
|
|
10
|
+
</div>
|
|
11
|
+
<div class="ef-field">
|
|
12
|
+
<label class="ef-field__label" for="form-row-birth-date">Date of birth</label>
|
|
13
|
+
<input id="form-row-birth-date" name="birth-date" type="date" autocomplete="bday">
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
@@ -670,6 +670,16 @@
|
|
|
670
670
|
"status": "requires-published-figma-component"
|
|
671
671
|
}
|
|
672
672
|
},
|
|
673
|
+
{
|
|
674
|
+
"id": "form-row",
|
|
675
|
+
"figmaName": "Forma / Form Row",
|
|
676
|
+
"source": "patterns/form-row.html",
|
|
677
|
+
"codeConnect": {
|
|
678
|
+
"id": "Forma/form-row",
|
|
679
|
+
"nodeUrl": null,
|
|
680
|
+
"status": "requires-published-figma-component"
|
|
681
|
+
}
|
|
682
|
+
},
|
|
673
683
|
{
|
|
674
684
|
"id": "grid",
|
|
675
685
|
"figmaName": "Forma / Grid",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@echelon-foundry/design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Zero-runtime HTML and CSS design system for Echelon Foundry applications.",
|
|
@@ -64,11 +64,11 @@
|
|
|
64
64
|
"test:motion": "node --test tests/motion-audit.test.mjs tests/motion-gate.test.mjs && node tools/motion-audit.mjs --strict",
|
|
65
65
|
"check": "npm run build && npm run icons:check && npm run test:tokens && npm run test:brands && npm run test:runtime && npm run test:motion && npm run test:marketing && npm run test:character-grid && npm run test:figma && npm run test:css && npm run test:package && npm run workflow:test && npm run workflow:build && npm run test:workflow-package && npm run test:browser",
|
|
66
66
|
"site:build": "npm run build && node tools/build-site.mjs",
|
|
67
|
-
"site:test": "node --test tests/site-build.test.mjs tests/catalog-coverage.test.mjs tests/icon-docs.test.mjs",
|
|
67
|
+
"site:test": "node --test tests/site-build.test.mjs tests/catalog-coverage.test.mjs tests/icon-docs.test.mjs tests/catalog-interaction.test.mjs",
|
|
68
68
|
"site:check": "npm run site:build && npm run catalog:check && npm run site:test && npm run site:mobile",
|
|
69
69
|
"site:mobile": "playwright test --config=playwright.site.config.mjs",
|
|
70
70
|
"pack:verify": "npm run build && npm pack --dry-run",
|
|
71
|
-
"test:package": "node --test tests/package-contract.test.mjs",
|
|
71
|
+
"test:package": "node --test tests/package-contract.test.mjs tests/conformance-package.test.mjs",
|
|
72
72
|
"test:css": "node --test tests/css-source.test.mjs tests/dist-css.test.mjs tests/contrast-pairs.test.mjs tests/diagram-contract.test.mjs",
|
|
73
73
|
"test:contrast": "node --test tests/contrast-pairs.test.mjs && playwright test tests/browser/pattern-contrast.spec.mjs --project=chromium",
|
|
74
74
|
"brands:build": "dotnet run --project tools/BrandCompiler/BrandCompiler.fsproj -- brands dist/brands",
|
|
@@ -90,6 +90,7 @@
|
|
|
90
90
|
"test:workflow-browser": "playwright test tests/browser/workflow-static.spec.mjs tests/browser/workflow-embed.spec.mjs",
|
|
91
91
|
"workflow:check": "npm run workflow:test && npm run workflow:build && npm run test:workflow-package && npm run test:workflow-browser",
|
|
92
92
|
"test:machine": "playwright test tests/browser/machine-operability.spec.mjs",
|
|
93
|
+
"ui:conformance": "npm run site:build && npm run catalog:check && npm run test:package && playwright test --config=playwright.conformance.config.mjs",
|
|
93
94
|
"icons:check": "node --test tests/icons.test.mjs"
|
|
94
95
|
},
|
|
95
96
|
"devDependencies": {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<div class="ef-form-row">
|
|
2
|
+
<div class="ef-field">
|
|
3
|
+
<label class="ef-field__label" for="form-row-given-name">Given name</label>
|
|
4
|
+
<input id="form-row-given-name" name="given-name" type="text" autocomplete="given-name">
|
|
5
|
+
</div>
|
|
6
|
+
<div class="ef-field">
|
|
7
|
+
<label class="ef-field__label" for="form-row-family-name">Family name</label>
|
|
8
|
+
<span class="ef-field__description" id="form-row-family-name-description">As printed on your passport or national identity card.</span>
|
|
9
|
+
<input id="form-row-family-name" name="family-name" type="text" autocomplete="family-name" aria-describedby="form-row-family-name-description">
|
|
10
|
+
</div>
|
|
11
|
+
<div class="ef-field">
|
|
12
|
+
<label class="ef-field__label" for="form-row-birth-date">Date of birth</label>
|
|
13
|
+
<input id="form-row-birth-date" name="birth-date" type="date" autocomplete="bday">
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|