@echelon-foundry/design-system 0.10.0 → 0.11.0-main.259.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 CHANGED
@@ -7,6 +7,21 @@ 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.11.0
11
+
12
+ Minor release: typography roles (EII-F, `.praxis/inbox/documents/2026-10-28-EII-F-typography-roles.md`).
13
+
14
+ ### Added
15
+ - **Typography roles.** `data-ef-type="application"`, `"dense"` and `"accessible"` select fixed heading and body steps from existing tokens: application h1/h2/h3 2xl/xl/lg with no ch caps; dense one step smaller with snug leading; accessible one step larger with relaxed leading. Marketing stays the default. Roles work in the `.ef-site` shell and on the application layer alone. See `docs/CONSUMING-FORMA.md`, "Typography roles".
16
+ - **Role tokens `--ef-type-measure-h1` / `--ef-type-measure-h2`.** They carry the existing 14ch/18ch marketing heading measures so a role can lift them.
17
+ - **`@echelon-foundry/forma-conformance`: rendered corner check.** `evaluateCornerContainment`, `resolveCornerRadius`, `measureCornerContainment` and `expectTextInsideCorners` port the layout probe's `boundary.corner` (LCE-001) to consumers. Released with the package's next version.
18
+ - **Browser regressions.** `tests/browser/type-roles.spec.mjs` (R5 heading scale, role steps, containment, overlap, clipping, focus, keyboard, 320-1280px, 200% text) and `tests/browser/corner-containment.spec.mjs` (LCE-001 padding cap under pill and 50% brand radii).
19
+
20
+ ### Fixed (opt-in)
21
+ - An application screen on the `.ef-site` shell no longer has to inherit the marketing display scale (h1 up to 7.25rem at 14ch), which the R5 rehearsal overrode locally.
22
+ - On the application layer, wrapped h1/h2 lines under a role use snug leading; with the core 1.02 line-height their glyph boxes overlapped at 200% text.
23
+
24
+
10
25
  ## 0.10.0
11
26
 
12
27
  Minor release: layout constraint enforcement (LCE-001, `experiments/LCE-001/REPORT.md`). `@echelon-foundry/forma-workflow` 1.1.0 ships the matching engine.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "format": "forma.color-contract/1.0.0",
3
- "formaVersion": "0.10.0",
3
+ "formaVersion": "0.11.0",
4
4
  "validationScope": "CSS var() references to --ef-color-* plus reserved internal color-related prefixes; other Forma APIs are governed by their own contracts.",
5
5
  "compatibility": {
6
6
  "policy": "Validate with the contract shipped by the pinned Forma package version.",
package/dist/all.css CHANGED
@@ -906,6 +906,108 @@
906
906
  :where(.ef-stack, .ef-grid, .ef-responsive-grid, .ef-priority-stack)[data-density] { gap: var(--ef-density-space); }
907
907
  @media (max-width: 48rem) { .ef-rail, .ef-rail[data-side="end"], .ef-focus-stage { grid-template-columns: minmax(0, 1fr); } .ef-mosaic { grid-template-columns: repeat(2, minmax(0, 1fr)); } .ef-span-2 { grid-column: 1 / -1; } }
908
908
  @media (max-width: 30rem) { .ef-mosaic { grid-template-columns: minmax(0, 1fr); } .ef-mosaic > [data-span="2"], .ef-mosaic > [data-span="full"] { grid-column: auto; } .ef-responsive-grid { --ef-responsive-grid-min: 100%; } .ef-priority-stack { --ef-priority-min: 100%; } }
909
+
910
+ /*
911
+ * Typography roles (EII-F). data-ef-type selects a role on any element,
912
+ * usually <html> or <body>; the nearest role wins:
913
+ * marketing the default (no attribute needed): the marketing layer's
914
+ * fluid display scale and heading measures, unchanged.
915
+ * application fixed steps for tools: h1 2xl, h2 xl, h3 lg, no ch caps.
916
+ * dense administrative density: one step smaller, snug leading.
917
+ * accessible large text: one step larger, relaxed leading.
918
+ * A role restates the type role tokens that the marketing layer
919
+ * (src/marketing/roles.css) and its themes declare, using only primitive
920
+ * steps. This layer follows echelon.tokens, so a role overrides a theme's
921
+ * :root role values; the .ef-site shell consumes the same tokens. The rules
922
+ * below give the application layer, which has no heading scale of its own,
923
+ * the same headings. Component headings (later layers) keep their sizes.
924
+ */
925
+ :where([data-ef-type="application"]) {
926
+ --ef-type-size-h1: var(--ef-primitive-font-size-2xl);
927
+ --ef-type-size-h2: var(--ef-primitive-font-size-xl);
928
+ --ef-type-size-h3: var(--ef-primitive-font-size-lg);
929
+ --ef-type-size-h4: var(--ef-primitive-font-size-md);
930
+ --ef-type-size-body: var(--ef-primitive-font-size-md);
931
+ --ef-type-size-lead: var(--ef-primitive-font-size-lg);
932
+ --ef-type-size-statement: var(--ef-primitive-font-size-xl);
933
+ --ef-type-size-small: var(--ef-primitive-font-size-sm);
934
+ --ef-type-size-label: var(--ef-primitive-font-size-xs);
935
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
936
+ --ef-type-leading-snug: var(--ef-primitive-line-height-snug);
937
+ --ef-type-leading-body: var(--ef-primitive-line-height-normal);
938
+ --ef-type-leading-lead: var(--ef-primitive-line-height-normal);
939
+ --ef-type-measure-h1: none;
940
+ --ef-type-measure-h2: none;
941
+ }
942
+
943
+ :where([data-ef-type="dense"]) {
944
+ --ef-type-size-h1: var(--ef-primitive-font-size-xl);
945
+ --ef-type-size-h2: var(--ef-primitive-font-size-lg);
946
+ --ef-type-size-h3: var(--ef-primitive-font-size-md);
947
+ --ef-type-size-h4: var(--ef-primitive-font-size-sm);
948
+ --ef-type-size-body: var(--ef-primitive-font-size-sm);
949
+ --ef-type-size-lead: var(--ef-primitive-font-size-md);
950
+ --ef-type-size-statement: var(--ef-primitive-font-size-lg);
951
+ --ef-type-size-small: var(--ef-primitive-font-size-xs);
952
+ --ef-type-size-label: var(--ef-primitive-font-size-xs);
953
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
954
+ --ef-type-leading-snug: var(--ef-primitive-line-height-snug);
955
+ --ef-type-leading-body: var(--ef-primitive-line-height-snug);
956
+ --ef-type-leading-lead: var(--ef-primitive-line-height-snug);
957
+ --ef-type-measure-h1: none;
958
+ --ef-type-measure-h2: none;
959
+ }
960
+
961
+ :where([data-ef-type="accessible"]) {
962
+ --ef-type-size-h1: var(--ef-primitive-font-size-3xl);
963
+ --ef-type-size-h2: var(--ef-primitive-font-size-2xl);
964
+ --ef-type-size-h3: var(--ef-primitive-font-size-xl);
965
+ --ef-type-size-h4: var(--ef-primitive-font-size-lg);
966
+ --ef-type-size-body: var(--ef-primitive-font-size-lg);
967
+ --ef-type-size-lead: var(--ef-primitive-font-size-xl);
968
+ --ef-type-size-statement: var(--ef-primitive-font-size-2xl);
969
+ --ef-type-size-small: var(--ef-primitive-font-size-md);
970
+ --ef-type-size-label: var(--ef-primitive-font-size-sm);
971
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
972
+ --ef-type-leading-snug: var(--ef-primitive-line-height-normal);
973
+ --ef-type-leading-body: var(--ef-primitive-line-height-relaxed);
974
+ --ef-type-leading-lead: var(--ef-primitive-line-height-relaxed);
975
+ --ef-type-measure-h1: none;
976
+ --ef-type-measure-h2: none;
977
+ }
978
+
979
+ /* Body text takes the role on <body> or the role element, never on <html>
980
+ itself, so rem keeps meaning the user's default text size. */
981
+ :where(
982
+ html[data-ef-type="application"] > body, :not(html)[data-ef-type="application"],
983
+ html[data-ef-type="dense"] > body, :not(html)[data-ef-type="dense"],
984
+ html[data-ef-type="accessible"] > body, :not(html)[data-ef-type="accessible"]
985
+ ) {
986
+ font-size: var(--ef-type-size-body);
987
+ line-height: var(--ef-type-leading-body);
988
+ }
989
+
990
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h1) {
991
+ font-size: var(--ef-type-size-h1);
992
+ line-height: var(--ef-type-leading-heading);
993
+ max-inline-size: var(--ef-type-measure-h1);
994
+ }
995
+
996
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h2) {
997
+ font-size: var(--ef-type-size-h2);
998
+ line-height: var(--ef-type-leading-heading);
999
+ max-inline-size: var(--ef-type-measure-h2);
1000
+ }
1001
+
1002
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h3) {
1003
+ font-size: var(--ef-type-size-h3);
1004
+ line-height: var(--ef-type-leading-snug);
1005
+ }
1006
+
1007
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h4, h5, h6) {
1008
+ font-size: var(--ef-type-size-h4);
1009
+ line-height: var(--ef-type-leading-snug);
1010
+ }
909
1011
  }
910
1012
 
911
1013
  /*
@@ -7658,6 +7760,10 @@
7658
7760
  --ef-type-size-h3: var(--ef-primitive-font-size-lg);
7659
7761
  --ef-type-size-h4: var(--ef-primitive-font-size-md);
7660
7762
  --ef-type-size-statement: var(--ef-primitive-font-size-fluid-display-3);
7763
+ /* Display heading measures. A typography role (data-ef-type, see
7764
+ src/styles/foundations.css) lifts them for application screens. */
7765
+ --ef-type-measure-h1: 14ch;
7766
+ --ef-type-measure-h2: 18ch;
7661
7767
  --ef-type-leading-body: var(--ef-primitive-line-height-normal);
7662
7768
  --ef-type-leading-lead: var(--ef-primitive-line-height-normal);
7663
7769
  --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
@@ -7850,8 +7956,8 @@
7850
7956
  line-height: var(--ef-type-leading-heading);
7851
7957
  }
7852
7958
 
7853
- .ef-site :where(h1) { font-size: var(--ef-type-size-h1); max-inline-size: 14ch; }
7854
- .ef-site :where(h2) { font-size: var(--ef-type-size-h2); max-inline-size: 18ch; }
7959
+ .ef-site :where(h1) { font-size: var(--ef-type-size-h1); max-inline-size: var(--ef-type-measure-h1); }
7960
+ .ef-site :where(h2) { font-size: var(--ef-type-size-h2); max-inline-size: var(--ef-type-measure-h2); }
7855
7961
  .ef-site :where(h3) { font-size: var(--ef-type-size-h3); line-height: var(--ef-type-leading-snug); }
7856
7962
  .ef-site :where(h4, h5, h6) { font-size: var(--ef-type-size-h4); line-height: var(--ef-type-leading-snug); }
7857
7963
 
@@ -342,13 +342,13 @@
342
342
  "tokens.css"
343
343
  ],
344
344
  "bytes": {
345
- "all.css": 336382,
345
+ "all.css": 341701,
346
346
  "assessment.css": 36343,
347
347
  "brands/echelon.css": 4213,
348
348
  "brands/example-harbor.css": 4229,
349
349
  "brands/index.json": 335,
350
350
  "components.css": 213356,
351
- "foundations.css": 15326,
351
+ "foundations.css": 20395,
352
352
  "icons/add.svg": 216,
353
353
  "icons/agent.svg": 354,
354
354
  "icons/archive.svg": 248,
@@ -510,7 +510,7 @@
510
510
  "icons/warning.svg": 324,
511
511
  "icons/wifi-off.svg": 269,
512
512
  "icons/workflow.svg": 345,
513
- "marketing.css": 47618,
513
+ "marketing.css": 47868,
514
514
  "patterns/active-filter-summary.html": 532,
515
515
  "patterns/alert.html": 384,
516
516
  "patterns/allocation.html": 1033,
@@ -295,4 +295,106 @@
295
295
  :where(.ef-stack, .ef-grid, .ef-responsive-grid, .ef-priority-stack)[data-density] { gap: var(--ef-density-space); }
296
296
  @media (max-width: 48rem) { .ef-rail, .ef-rail[data-side="end"], .ef-focus-stage { grid-template-columns: minmax(0, 1fr); } .ef-mosaic { grid-template-columns: repeat(2, minmax(0, 1fr)); } .ef-span-2 { grid-column: 1 / -1; } }
297
297
  @media (max-width: 30rem) { .ef-mosaic { grid-template-columns: minmax(0, 1fr); } .ef-mosaic > [data-span="2"], .ef-mosaic > [data-span="full"] { grid-column: auto; } .ef-responsive-grid { --ef-responsive-grid-min: 100%; } .ef-priority-stack { --ef-priority-min: 100%; } }
298
+
299
+ /*
300
+ * Typography roles (EII-F). data-ef-type selects a role on any element,
301
+ * usually <html> or <body>; the nearest role wins:
302
+ * marketing the default (no attribute needed): the marketing layer's
303
+ * fluid display scale and heading measures, unchanged.
304
+ * application fixed steps for tools: h1 2xl, h2 xl, h3 lg, no ch caps.
305
+ * dense administrative density: one step smaller, snug leading.
306
+ * accessible large text: one step larger, relaxed leading.
307
+ * A role restates the type role tokens that the marketing layer
308
+ * (src/marketing/roles.css) and its themes declare, using only primitive
309
+ * steps. This layer follows echelon.tokens, so a role overrides a theme's
310
+ * :root role values; the .ef-site shell consumes the same tokens. The rules
311
+ * below give the application layer, which has no heading scale of its own,
312
+ * the same headings. Component headings (later layers) keep their sizes.
313
+ */
314
+ :where([data-ef-type="application"]) {
315
+ --ef-type-size-h1: var(--ef-primitive-font-size-2xl);
316
+ --ef-type-size-h2: var(--ef-primitive-font-size-xl);
317
+ --ef-type-size-h3: var(--ef-primitive-font-size-lg);
318
+ --ef-type-size-h4: var(--ef-primitive-font-size-md);
319
+ --ef-type-size-body: var(--ef-primitive-font-size-md);
320
+ --ef-type-size-lead: var(--ef-primitive-font-size-lg);
321
+ --ef-type-size-statement: var(--ef-primitive-font-size-xl);
322
+ --ef-type-size-small: var(--ef-primitive-font-size-sm);
323
+ --ef-type-size-label: var(--ef-primitive-font-size-xs);
324
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
325
+ --ef-type-leading-snug: var(--ef-primitive-line-height-snug);
326
+ --ef-type-leading-body: var(--ef-primitive-line-height-normal);
327
+ --ef-type-leading-lead: var(--ef-primitive-line-height-normal);
328
+ --ef-type-measure-h1: none;
329
+ --ef-type-measure-h2: none;
330
+ }
331
+
332
+ :where([data-ef-type="dense"]) {
333
+ --ef-type-size-h1: var(--ef-primitive-font-size-xl);
334
+ --ef-type-size-h2: var(--ef-primitive-font-size-lg);
335
+ --ef-type-size-h3: var(--ef-primitive-font-size-md);
336
+ --ef-type-size-h4: var(--ef-primitive-font-size-sm);
337
+ --ef-type-size-body: var(--ef-primitive-font-size-sm);
338
+ --ef-type-size-lead: var(--ef-primitive-font-size-md);
339
+ --ef-type-size-statement: var(--ef-primitive-font-size-lg);
340
+ --ef-type-size-small: var(--ef-primitive-font-size-xs);
341
+ --ef-type-size-label: var(--ef-primitive-font-size-xs);
342
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
343
+ --ef-type-leading-snug: var(--ef-primitive-line-height-snug);
344
+ --ef-type-leading-body: var(--ef-primitive-line-height-snug);
345
+ --ef-type-leading-lead: var(--ef-primitive-line-height-snug);
346
+ --ef-type-measure-h1: none;
347
+ --ef-type-measure-h2: none;
348
+ }
349
+
350
+ :where([data-ef-type="accessible"]) {
351
+ --ef-type-size-h1: var(--ef-primitive-font-size-3xl);
352
+ --ef-type-size-h2: var(--ef-primitive-font-size-2xl);
353
+ --ef-type-size-h3: var(--ef-primitive-font-size-xl);
354
+ --ef-type-size-h4: var(--ef-primitive-font-size-lg);
355
+ --ef-type-size-body: var(--ef-primitive-font-size-lg);
356
+ --ef-type-size-lead: var(--ef-primitive-font-size-xl);
357
+ --ef-type-size-statement: var(--ef-primitive-font-size-2xl);
358
+ --ef-type-size-small: var(--ef-primitive-font-size-md);
359
+ --ef-type-size-label: var(--ef-primitive-font-size-sm);
360
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
361
+ --ef-type-leading-snug: var(--ef-primitive-line-height-normal);
362
+ --ef-type-leading-body: var(--ef-primitive-line-height-relaxed);
363
+ --ef-type-leading-lead: var(--ef-primitive-line-height-relaxed);
364
+ --ef-type-measure-h1: none;
365
+ --ef-type-measure-h2: none;
366
+ }
367
+
368
+ /* Body text takes the role on <body> or the role element, never on <html>
369
+ itself, so rem keeps meaning the user's default text size. */
370
+ :where(
371
+ html[data-ef-type="application"] > body, :not(html)[data-ef-type="application"],
372
+ html[data-ef-type="dense"] > body, :not(html)[data-ef-type="dense"],
373
+ html[data-ef-type="accessible"] > body, :not(html)[data-ef-type="accessible"]
374
+ ) {
375
+ font-size: var(--ef-type-size-body);
376
+ line-height: var(--ef-type-leading-body);
377
+ }
378
+
379
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h1) {
380
+ font-size: var(--ef-type-size-h1);
381
+ line-height: var(--ef-type-leading-heading);
382
+ max-inline-size: var(--ef-type-measure-h1);
383
+ }
384
+
385
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h2) {
386
+ font-size: var(--ef-type-size-h2);
387
+ line-height: var(--ef-type-leading-heading);
388
+ max-inline-size: var(--ef-type-measure-h2);
389
+ }
390
+
391
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h3) {
392
+ font-size: var(--ef-type-size-h3);
393
+ line-height: var(--ef-type-leading-snug);
394
+ }
395
+
396
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h4, h5, h6) {
397
+ font-size: var(--ef-type-size-h4);
398
+ line-height: var(--ef-type-leading-snug);
399
+ }
298
400
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "formaVersion": "0.10.0",
3
+ "formaVersion": "0.11.0",
4
4
  "grid": 24,
5
5
  "icons": [
6
6
  {
@@ -1,4 +1,4 @@
1
- /*! Forma 0.10.0 | forma-all.css | bundle echelon-marketing
1
+ /*! Forma 0.11.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
 
@@ -911,6 +911,108 @@
911
911
  :where(.ef-stack, .ef-grid, .ef-responsive-grid, .ef-priority-stack)[data-density] { gap: var(--ef-density-space); }
912
912
  @media (max-width: 48rem) { .ef-rail, .ef-rail[data-side="end"], .ef-focus-stage { grid-template-columns: minmax(0, 1fr); } .ef-mosaic { grid-template-columns: repeat(2, minmax(0, 1fr)); } .ef-span-2 { grid-column: 1 / -1; } }
913
913
  @media (max-width: 30rem) { .ef-mosaic { grid-template-columns: minmax(0, 1fr); } .ef-mosaic > [data-span="2"], .ef-mosaic > [data-span="full"] { grid-column: auto; } .ef-responsive-grid { --ef-responsive-grid-min: 100%; } .ef-priority-stack { --ef-priority-min: 100%; } }
914
+
915
+ /*
916
+ * Typography roles (EII-F). data-ef-type selects a role on any element,
917
+ * usually <html> or <body>; the nearest role wins:
918
+ * marketing the default (no attribute needed): the marketing layer's
919
+ * fluid display scale and heading measures, unchanged.
920
+ * application fixed steps for tools: h1 2xl, h2 xl, h3 lg, no ch caps.
921
+ * dense administrative density: one step smaller, snug leading.
922
+ * accessible large text: one step larger, relaxed leading.
923
+ * A role restates the type role tokens that the marketing layer
924
+ * (src/marketing/roles.css) and its themes declare, using only primitive
925
+ * steps. This layer follows echelon.tokens, so a role overrides a theme's
926
+ * :root role values; the .ef-site shell consumes the same tokens. The rules
927
+ * below give the application layer, which has no heading scale of its own,
928
+ * the same headings. Component headings (later layers) keep their sizes.
929
+ */
930
+ :where([data-ef-type="application"]) {
931
+ --ef-type-size-h1: var(--ef-primitive-font-size-2xl);
932
+ --ef-type-size-h2: var(--ef-primitive-font-size-xl);
933
+ --ef-type-size-h3: var(--ef-primitive-font-size-lg);
934
+ --ef-type-size-h4: var(--ef-primitive-font-size-md);
935
+ --ef-type-size-body: var(--ef-primitive-font-size-md);
936
+ --ef-type-size-lead: var(--ef-primitive-font-size-lg);
937
+ --ef-type-size-statement: var(--ef-primitive-font-size-xl);
938
+ --ef-type-size-small: var(--ef-primitive-font-size-sm);
939
+ --ef-type-size-label: var(--ef-primitive-font-size-xs);
940
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
941
+ --ef-type-leading-snug: var(--ef-primitive-line-height-snug);
942
+ --ef-type-leading-body: var(--ef-primitive-line-height-normal);
943
+ --ef-type-leading-lead: var(--ef-primitive-line-height-normal);
944
+ --ef-type-measure-h1: none;
945
+ --ef-type-measure-h2: none;
946
+ }
947
+
948
+ :where([data-ef-type="dense"]) {
949
+ --ef-type-size-h1: var(--ef-primitive-font-size-xl);
950
+ --ef-type-size-h2: var(--ef-primitive-font-size-lg);
951
+ --ef-type-size-h3: var(--ef-primitive-font-size-md);
952
+ --ef-type-size-h4: var(--ef-primitive-font-size-sm);
953
+ --ef-type-size-body: var(--ef-primitive-font-size-sm);
954
+ --ef-type-size-lead: var(--ef-primitive-font-size-md);
955
+ --ef-type-size-statement: var(--ef-primitive-font-size-lg);
956
+ --ef-type-size-small: var(--ef-primitive-font-size-xs);
957
+ --ef-type-size-label: var(--ef-primitive-font-size-xs);
958
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
959
+ --ef-type-leading-snug: var(--ef-primitive-line-height-snug);
960
+ --ef-type-leading-body: var(--ef-primitive-line-height-snug);
961
+ --ef-type-leading-lead: var(--ef-primitive-line-height-snug);
962
+ --ef-type-measure-h1: none;
963
+ --ef-type-measure-h2: none;
964
+ }
965
+
966
+ :where([data-ef-type="accessible"]) {
967
+ --ef-type-size-h1: var(--ef-primitive-font-size-3xl);
968
+ --ef-type-size-h2: var(--ef-primitive-font-size-2xl);
969
+ --ef-type-size-h3: var(--ef-primitive-font-size-xl);
970
+ --ef-type-size-h4: var(--ef-primitive-font-size-lg);
971
+ --ef-type-size-body: var(--ef-primitive-font-size-lg);
972
+ --ef-type-size-lead: var(--ef-primitive-font-size-xl);
973
+ --ef-type-size-statement: var(--ef-primitive-font-size-2xl);
974
+ --ef-type-size-small: var(--ef-primitive-font-size-md);
975
+ --ef-type-size-label: var(--ef-primitive-font-size-sm);
976
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
977
+ --ef-type-leading-snug: var(--ef-primitive-line-height-normal);
978
+ --ef-type-leading-body: var(--ef-primitive-line-height-relaxed);
979
+ --ef-type-leading-lead: var(--ef-primitive-line-height-relaxed);
980
+ --ef-type-measure-h1: none;
981
+ --ef-type-measure-h2: none;
982
+ }
983
+
984
+ /* Body text takes the role on <body> or the role element, never on <html>
985
+ itself, so rem keeps meaning the user's default text size. */
986
+ :where(
987
+ html[data-ef-type="application"] > body, :not(html)[data-ef-type="application"],
988
+ html[data-ef-type="dense"] > body, :not(html)[data-ef-type="dense"],
989
+ html[data-ef-type="accessible"] > body, :not(html)[data-ef-type="accessible"]
990
+ ) {
991
+ font-size: var(--ef-type-size-body);
992
+ line-height: var(--ef-type-leading-body);
993
+ }
994
+
995
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h1) {
996
+ font-size: var(--ef-type-size-h1);
997
+ line-height: var(--ef-type-leading-heading);
998
+ max-inline-size: var(--ef-type-measure-h1);
999
+ }
1000
+
1001
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h2) {
1002
+ font-size: var(--ef-type-size-h2);
1003
+ line-height: var(--ef-type-leading-heading);
1004
+ max-inline-size: var(--ef-type-measure-h2);
1005
+ }
1006
+
1007
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h3) {
1008
+ font-size: var(--ef-type-size-h3);
1009
+ line-height: var(--ef-type-leading-snug);
1010
+ }
1011
+
1012
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h4, h5, h6) {
1013
+ font-size: var(--ef-type-size-h4);
1014
+ line-height: var(--ef-type-leading-snug);
1015
+ }
914
1016
  }
915
1017
 
916
1018
  /*
@@ -7663,6 +7765,10 @@
7663
7765
  --ef-type-size-h3: var(--ef-primitive-font-size-lg);
7664
7766
  --ef-type-size-h4: var(--ef-primitive-font-size-md);
7665
7767
  --ef-type-size-statement: var(--ef-primitive-font-size-fluid-display-3);
7768
+ /* Display heading measures. A typography role (data-ef-type, see
7769
+ src/styles/foundations.css) lifts them for application screens. */
7770
+ --ef-type-measure-h1: 14ch;
7771
+ --ef-type-measure-h2: 18ch;
7666
7772
  --ef-type-leading-body: var(--ef-primitive-line-height-normal);
7667
7773
  --ef-type-leading-lead: var(--ef-primitive-line-height-normal);
7668
7774
  --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
@@ -7855,8 +7961,8 @@
7855
7961
  line-height: var(--ef-type-leading-heading);
7856
7962
  }
7857
7963
 
7858
- .ef-site :where(h1) { font-size: var(--ef-type-size-h1); max-inline-size: 14ch; }
7859
- .ef-site :where(h2) { font-size: var(--ef-type-size-h2); max-inline-size: 18ch; }
7964
+ .ef-site :where(h1) { font-size: var(--ef-type-size-h1); max-inline-size: var(--ef-type-measure-h1); }
7965
+ .ef-site :where(h2) { font-size: var(--ef-type-size-h2); max-inline-size: var(--ef-type-measure-h2); }
7860
7966
  .ef-site :where(h3) { font-size: var(--ef-type-size-h3); line-height: var(--ef-type-leading-snug); }
7861
7967
  .ef-site :where(h4, h5, h6) { font-size: var(--ef-type-size-h4); line-height: var(--ef-type-leading-snug); }
7862
7968
 
@@ -1,4 +1,4 @@
1
- /*! Forma 0.10.0 | forma-echelon-marketing.css | bundle echelon-marketing
1
+ /*! Forma 0.11.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
 
@@ -665,6 +665,10 @@
665
665
  --ef-type-size-h3: var(--ef-primitive-font-size-lg);
666
666
  --ef-type-size-h4: var(--ef-primitive-font-size-md);
667
667
  --ef-type-size-statement: var(--ef-primitive-font-size-fluid-display-3);
668
+ /* Display heading measures. A typography role (data-ef-type, see
669
+ src/styles/foundations.css) lifts them for application screens. */
670
+ --ef-type-measure-h1: 14ch;
671
+ --ef-type-measure-h2: 18ch;
668
672
  --ef-type-leading-body: var(--ef-primitive-line-height-normal);
669
673
  --ef-type-leading-lead: var(--ef-primitive-line-height-normal);
670
674
  --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
@@ -1011,6 +1015,108 @@
1011
1015
  :where(.ef-stack, .ef-grid, .ef-responsive-grid, .ef-priority-stack)[data-density] { gap: var(--ef-density-space); }
1012
1016
  @media (max-width: 48rem) { .ef-rail, .ef-rail[data-side="end"], .ef-focus-stage { grid-template-columns: minmax(0, 1fr); } .ef-mosaic { grid-template-columns: repeat(2, minmax(0, 1fr)); } .ef-span-2 { grid-column: 1 / -1; } }
1013
1017
  @media (max-width: 30rem) { .ef-mosaic { grid-template-columns: minmax(0, 1fr); } .ef-mosaic > [data-span="2"], .ef-mosaic > [data-span="full"] { grid-column: auto; } .ef-responsive-grid { --ef-responsive-grid-min: 100%; } .ef-priority-stack { --ef-priority-min: 100%; } }
1018
+
1019
+ /*
1020
+ * Typography roles (EII-F). data-ef-type selects a role on any element,
1021
+ * usually <html> or <body>; the nearest role wins:
1022
+ * marketing the default (no attribute needed): the marketing layer's
1023
+ * fluid display scale and heading measures, unchanged.
1024
+ * application fixed steps for tools: h1 2xl, h2 xl, h3 lg, no ch caps.
1025
+ * dense administrative density: one step smaller, snug leading.
1026
+ * accessible large text: one step larger, relaxed leading.
1027
+ * A role restates the type role tokens that the marketing layer
1028
+ * (src/marketing/roles.css) and its themes declare, using only primitive
1029
+ * steps. This layer follows echelon.tokens, so a role overrides a theme's
1030
+ * :root role values; the .ef-site shell consumes the same tokens. The rules
1031
+ * below give the application layer, which has no heading scale of its own,
1032
+ * the same headings. Component headings (later layers) keep their sizes.
1033
+ */
1034
+ :where([data-ef-type="application"]) {
1035
+ --ef-type-size-h1: var(--ef-primitive-font-size-2xl);
1036
+ --ef-type-size-h2: var(--ef-primitive-font-size-xl);
1037
+ --ef-type-size-h3: var(--ef-primitive-font-size-lg);
1038
+ --ef-type-size-h4: var(--ef-primitive-font-size-md);
1039
+ --ef-type-size-body: var(--ef-primitive-font-size-md);
1040
+ --ef-type-size-lead: var(--ef-primitive-font-size-lg);
1041
+ --ef-type-size-statement: var(--ef-primitive-font-size-xl);
1042
+ --ef-type-size-small: var(--ef-primitive-font-size-sm);
1043
+ --ef-type-size-label: var(--ef-primitive-font-size-xs);
1044
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
1045
+ --ef-type-leading-snug: var(--ef-primitive-line-height-snug);
1046
+ --ef-type-leading-body: var(--ef-primitive-line-height-normal);
1047
+ --ef-type-leading-lead: var(--ef-primitive-line-height-normal);
1048
+ --ef-type-measure-h1: none;
1049
+ --ef-type-measure-h2: none;
1050
+ }
1051
+
1052
+ :where([data-ef-type="dense"]) {
1053
+ --ef-type-size-h1: var(--ef-primitive-font-size-xl);
1054
+ --ef-type-size-h2: var(--ef-primitive-font-size-lg);
1055
+ --ef-type-size-h3: var(--ef-primitive-font-size-md);
1056
+ --ef-type-size-h4: var(--ef-primitive-font-size-sm);
1057
+ --ef-type-size-body: var(--ef-primitive-font-size-sm);
1058
+ --ef-type-size-lead: var(--ef-primitive-font-size-md);
1059
+ --ef-type-size-statement: var(--ef-primitive-font-size-lg);
1060
+ --ef-type-size-small: var(--ef-primitive-font-size-xs);
1061
+ --ef-type-size-label: var(--ef-primitive-font-size-xs);
1062
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
1063
+ --ef-type-leading-snug: var(--ef-primitive-line-height-snug);
1064
+ --ef-type-leading-body: var(--ef-primitive-line-height-snug);
1065
+ --ef-type-leading-lead: var(--ef-primitive-line-height-snug);
1066
+ --ef-type-measure-h1: none;
1067
+ --ef-type-measure-h2: none;
1068
+ }
1069
+
1070
+ :where([data-ef-type="accessible"]) {
1071
+ --ef-type-size-h1: var(--ef-primitive-font-size-3xl);
1072
+ --ef-type-size-h2: var(--ef-primitive-font-size-2xl);
1073
+ --ef-type-size-h3: var(--ef-primitive-font-size-xl);
1074
+ --ef-type-size-h4: var(--ef-primitive-font-size-lg);
1075
+ --ef-type-size-body: var(--ef-primitive-font-size-lg);
1076
+ --ef-type-size-lead: var(--ef-primitive-font-size-xl);
1077
+ --ef-type-size-statement: var(--ef-primitive-font-size-2xl);
1078
+ --ef-type-size-small: var(--ef-primitive-font-size-md);
1079
+ --ef-type-size-label: var(--ef-primitive-font-size-sm);
1080
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
1081
+ --ef-type-leading-snug: var(--ef-primitive-line-height-normal);
1082
+ --ef-type-leading-body: var(--ef-primitive-line-height-relaxed);
1083
+ --ef-type-leading-lead: var(--ef-primitive-line-height-relaxed);
1084
+ --ef-type-measure-h1: none;
1085
+ --ef-type-measure-h2: none;
1086
+ }
1087
+
1088
+ /* Body text takes the role on <body> or the role element, never on <html>
1089
+ itself, so rem keeps meaning the user's default text size. */
1090
+ :where(
1091
+ html[data-ef-type="application"] > body, :not(html)[data-ef-type="application"],
1092
+ html[data-ef-type="dense"] > body, :not(html)[data-ef-type="dense"],
1093
+ html[data-ef-type="accessible"] > body, :not(html)[data-ef-type="accessible"]
1094
+ ) {
1095
+ font-size: var(--ef-type-size-body);
1096
+ line-height: var(--ef-type-leading-body);
1097
+ }
1098
+
1099
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h1) {
1100
+ font-size: var(--ef-type-size-h1);
1101
+ line-height: var(--ef-type-leading-heading);
1102
+ max-inline-size: var(--ef-type-measure-h1);
1103
+ }
1104
+
1105
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h2) {
1106
+ font-size: var(--ef-type-size-h2);
1107
+ line-height: var(--ef-type-leading-heading);
1108
+ max-inline-size: var(--ef-type-measure-h2);
1109
+ }
1110
+
1111
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h3) {
1112
+ font-size: var(--ef-type-size-h3);
1113
+ line-height: var(--ef-type-leading-snug);
1114
+ }
1115
+
1116
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h4, h5, h6) {
1117
+ font-size: var(--ef-type-size-h4);
1118
+ line-height: var(--ef-type-leading-snug);
1119
+ }
1014
1120
  }
1015
1121
 
1016
1122
  /* --- source: src/marketing/foundations.css --- */
@@ -1158,8 +1264,8 @@
1158
1264
  line-height: var(--ef-type-leading-heading);
1159
1265
  }
1160
1266
 
1161
- .ef-site :where(h1) { font-size: var(--ef-type-size-h1); max-inline-size: 14ch; }
1162
- .ef-site :where(h2) { font-size: var(--ef-type-size-h2); max-inline-size: 18ch; }
1267
+ .ef-site :where(h1) { font-size: var(--ef-type-size-h1); max-inline-size: var(--ef-type-measure-h1); }
1268
+ .ef-site :where(h2) { font-size: var(--ef-type-size-h2); max-inline-size: var(--ef-type-measure-h2); }
1163
1269
  .ef-site :where(h3) { font-size: var(--ef-type-size-h3); line-height: var(--ef-type-leading-snug); }
1164
1270
  .ef-site :where(h4, h5, h6) { font-size: var(--ef-type-size-h4); line-height: var(--ef-type-leading-snug); }
1165
1271
 
@@ -1,4 +1,4 @@
1
- /*! Forma 0.10.0 | forma-marketing-theme-echelon.css | bundle echelon-marketing
1
+ /*! Forma 0.11.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.10.0 | forma-marketing.css | bundle echelon-marketing
1
+ /*! Forma 0.11.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
 
@@ -664,6 +664,10 @@
664
664
  --ef-type-size-h3: var(--ef-primitive-font-size-lg);
665
665
  --ef-type-size-h4: var(--ef-primitive-font-size-md);
666
666
  --ef-type-size-statement: var(--ef-primitive-font-size-fluid-display-3);
667
+ /* Display heading measures. A typography role (data-ef-type, see
668
+ src/styles/foundations.css) lifts them for application screens. */
669
+ --ef-type-measure-h1: 14ch;
670
+ --ef-type-measure-h2: 18ch;
667
671
  --ef-type-leading-body: var(--ef-primitive-line-height-normal);
668
672
  --ef-type-leading-lead: var(--ef-primitive-line-height-normal);
669
673
  --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
@@ -1010,6 +1014,108 @@
1010
1014
  :where(.ef-stack, .ef-grid, .ef-responsive-grid, .ef-priority-stack)[data-density] { gap: var(--ef-density-space); }
1011
1015
  @media (max-width: 48rem) { .ef-rail, .ef-rail[data-side="end"], .ef-focus-stage { grid-template-columns: minmax(0, 1fr); } .ef-mosaic { grid-template-columns: repeat(2, minmax(0, 1fr)); } .ef-span-2 { grid-column: 1 / -1; } }
1012
1016
  @media (max-width: 30rem) { .ef-mosaic { grid-template-columns: minmax(0, 1fr); } .ef-mosaic > [data-span="2"], .ef-mosaic > [data-span="full"] { grid-column: auto; } .ef-responsive-grid { --ef-responsive-grid-min: 100%; } .ef-priority-stack { --ef-priority-min: 100%; } }
1017
+
1018
+ /*
1019
+ * Typography roles (EII-F). data-ef-type selects a role on any element,
1020
+ * usually <html> or <body>; the nearest role wins:
1021
+ * marketing the default (no attribute needed): the marketing layer's
1022
+ * fluid display scale and heading measures, unchanged.
1023
+ * application fixed steps for tools: h1 2xl, h2 xl, h3 lg, no ch caps.
1024
+ * dense administrative density: one step smaller, snug leading.
1025
+ * accessible large text: one step larger, relaxed leading.
1026
+ * A role restates the type role tokens that the marketing layer
1027
+ * (src/marketing/roles.css) and its themes declare, using only primitive
1028
+ * steps. This layer follows echelon.tokens, so a role overrides a theme's
1029
+ * :root role values; the .ef-site shell consumes the same tokens. The rules
1030
+ * below give the application layer, which has no heading scale of its own,
1031
+ * the same headings. Component headings (later layers) keep their sizes.
1032
+ */
1033
+ :where([data-ef-type="application"]) {
1034
+ --ef-type-size-h1: var(--ef-primitive-font-size-2xl);
1035
+ --ef-type-size-h2: var(--ef-primitive-font-size-xl);
1036
+ --ef-type-size-h3: var(--ef-primitive-font-size-lg);
1037
+ --ef-type-size-h4: var(--ef-primitive-font-size-md);
1038
+ --ef-type-size-body: var(--ef-primitive-font-size-md);
1039
+ --ef-type-size-lead: var(--ef-primitive-font-size-lg);
1040
+ --ef-type-size-statement: var(--ef-primitive-font-size-xl);
1041
+ --ef-type-size-small: var(--ef-primitive-font-size-sm);
1042
+ --ef-type-size-label: var(--ef-primitive-font-size-xs);
1043
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
1044
+ --ef-type-leading-snug: var(--ef-primitive-line-height-snug);
1045
+ --ef-type-leading-body: var(--ef-primitive-line-height-normal);
1046
+ --ef-type-leading-lead: var(--ef-primitive-line-height-normal);
1047
+ --ef-type-measure-h1: none;
1048
+ --ef-type-measure-h2: none;
1049
+ }
1050
+
1051
+ :where([data-ef-type="dense"]) {
1052
+ --ef-type-size-h1: var(--ef-primitive-font-size-xl);
1053
+ --ef-type-size-h2: var(--ef-primitive-font-size-lg);
1054
+ --ef-type-size-h3: var(--ef-primitive-font-size-md);
1055
+ --ef-type-size-h4: var(--ef-primitive-font-size-sm);
1056
+ --ef-type-size-body: var(--ef-primitive-font-size-sm);
1057
+ --ef-type-size-lead: var(--ef-primitive-font-size-md);
1058
+ --ef-type-size-statement: var(--ef-primitive-font-size-lg);
1059
+ --ef-type-size-small: var(--ef-primitive-font-size-xs);
1060
+ --ef-type-size-label: var(--ef-primitive-font-size-xs);
1061
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
1062
+ --ef-type-leading-snug: var(--ef-primitive-line-height-snug);
1063
+ --ef-type-leading-body: var(--ef-primitive-line-height-snug);
1064
+ --ef-type-leading-lead: var(--ef-primitive-line-height-snug);
1065
+ --ef-type-measure-h1: none;
1066
+ --ef-type-measure-h2: none;
1067
+ }
1068
+
1069
+ :where([data-ef-type="accessible"]) {
1070
+ --ef-type-size-h1: var(--ef-primitive-font-size-3xl);
1071
+ --ef-type-size-h2: var(--ef-primitive-font-size-2xl);
1072
+ --ef-type-size-h3: var(--ef-primitive-font-size-xl);
1073
+ --ef-type-size-h4: var(--ef-primitive-font-size-lg);
1074
+ --ef-type-size-body: var(--ef-primitive-font-size-lg);
1075
+ --ef-type-size-lead: var(--ef-primitive-font-size-xl);
1076
+ --ef-type-size-statement: var(--ef-primitive-font-size-2xl);
1077
+ --ef-type-size-small: var(--ef-primitive-font-size-md);
1078
+ --ef-type-size-label: var(--ef-primitive-font-size-sm);
1079
+ --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
1080
+ --ef-type-leading-snug: var(--ef-primitive-line-height-normal);
1081
+ --ef-type-leading-body: var(--ef-primitive-line-height-relaxed);
1082
+ --ef-type-leading-lead: var(--ef-primitive-line-height-relaxed);
1083
+ --ef-type-measure-h1: none;
1084
+ --ef-type-measure-h2: none;
1085
+ }
1086
+
1087
+ /* Body text takes the role on <body> or the role element, never on <html>
1088
+ itself, so rem keeps meaning the user's default text size. */
1089
+ :where(
1090
+ html[data-ef-type="application"] > body, :not(html)[data-ef-type="application"],
1091
+ html[data-ef-type="dense"] > body, :not(html)[data-ef-type="dense"],
1092
+ html[data-ef-type="accessible"] > body, :not(html)[data-ef-type="accessible"]
1093
+ ) {
1094
+ font-size: var(--ef-type-size-body);
1095
+ line-height: var(--ef-type-leading-body);
1096
+ }
1097
+
1098
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h1) {
1099
+ font-size: var(--ef-type-size-h1);
1100
+ line-height: var(--ef-type-leading-heading);
1101
+ max-inline-size: var(--ef-type-measure-h1);
1102
+ }
1103
+
1104
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h2) {
1105
+ font-size: var(--ef-type-size-h2);
1106
+ line-height: var(--ef-type-leading-heading);
1107
+ max-inline-size: var(--ef-type-measure-h2);
1108
+ }
1109
+
1110
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h3) {
1111
+ font-size: var(--ef-type-size-h3);
1112
+ line-height: var(--ef-type-leading-snug);
1113
+ }
1114
+
1115
+ :where([data-ef-type="application"], [data-ef-type="dense"], [data-ef-type="accessible"]) :where(h4, h5, h6) {
1116
+ font-size: var(--ef-type-size-h4);
1117
+ line-height: var(--ef-type-leading-snug);
1118
+ }
1013
1119
  }
1014
1120
 
1015
1121
  /* --- source: src/marketing/foundations.css --- */
@@ -1157,8 +1263,8 @@
1157
1263
  line-height: var(--ef-type-leading-heading);
1158
1264
  }
1159
1265
 
1160
- .ef-site :where(h1) { font-size: var(--ef-type-size-h1); max-inline-size: 14ch; }
1161
- .ef-site :where(h2) { font-size: var(--ef-type-size-h2); max-inline-size: 18ch; }
1266
+ .ef-site :where(h1) { font-size: var(--ef-type-size-h1); max-inline-size: var(--ef-type-measure-h1); }
1267
+ .ef-site :where(h2) { font-size: var(--ef-type-size-h2); max-inline-size: var(--ef-type-measure-h2); }
1162
1268
  .ef-site :where(h3) { font-size: var(--ef-type-size-h3); line-height: var(--ef-type-leading-snug); }
1163
1269
  .ef-site :where(h4, h5, h6) { font-size: var(--ef-type-size-h4); line-height: var(--ef-type-leading-snug); }
1164
1270
 
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "forma": "0.10.0",
3
+ "forma": "0.11.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.10.0",
6
+ "releaseTag": "v0.11.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": 87243,
12
- "sha256": "d8a900aecd8aa4a72cbda731d3bbcfadbf872bc8aed1a8ef74f5ef3169af4cc6",
11
+ "bytes": 92562,
12
+ "sha256": "d15eb11a605676935a683fd1382bdecf2fd9c070893c80974766b4c22ab63b75",
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": 6296,
26
- "sha256": "e3e05cf66b87ac6be686896c353ab87f47ad1be589c1fc2895238d1bd987d9e6",
26
+ "sha256": "66fcf350b0d36535df6fcb6fbca32bc1236b31398c49eeccf3670342f38e5ac9",
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": 93383,
36
- "sha256": "837ddc667b3eccbc6a0512fe767708212a2aeffe18f9c2a27cbedad9be2937f3",
35
+ "bytes": 98702,
36
+ "sha256": "08975a531a7c4c8d2ec8c67e2c3998c4bbceaa25b8d1e5b1097a8420b85e6f12",
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": 336745,
46
- "sha256": "6666ea17b441934dd66807f9aefae86213ca228c92eed8da17faed2b2d816b18",
45
+ "bytes": 342064,
46
+ "sha256": "8355d917009ade27384b73f43e29c756ae9298e499e26b18cee7ba198edf4fcf",
47
47
  "sources": [
48
48
  "dist/all.css"
49
49
  ]
@@ -1,4 +1,4 @@
1
- d8a900aecd8aa4a72cbda731d3bbcfadbf872bc8aed1a8ef74f5ef3169af4cc6 forma-marketing.css
2
- e3e05cf66b87ac6be686896c353ab87f47ad1be589c1fc2895238d1bd987d9e6 forma-marketing-theme-echelon.css
3
- 837ddc667b3eccbc6a0512fe767708212a2aeffe18f9c2a27cbedad9be2937f3 forma-echelon-marketing.css
4
- 6666ea17b441934dd66807f9aefae86213ca228c92eed8da17faed2b2d816b18 forma-all.css
1
+ d15eb11a605676935a683fd1382bdecf2fd9c070893c80974766b4c22ab63b75 forma-marketing.css
2
+ 66fcf350b0d36535df6fcb6fbca32bc1236b31398c49eeccf3670342f38e5ac9 forma-marketing-theme-echelon.css
3
+ 08975a531a7c4c8d2ec8c67e2c3998c4bbceaa25b8d1e5b1097a8420b85e6f12 forma-echelon-marketing.css
4
+ 8355d917009ade27384b73f43e29c756ae9298e499e26b18cee7ba198edf4fcf forma-all.css
@@ -47,6 +47,10 @@
47
47
  --ef-type-size-h3: var(--ef-primitive-font-size-lg);
48
48
  --ef-type-size-h4: var(--ef-primitive-font-size-md);
49
49
  --ef-type-size-statement: var(--ef-primitive-font-size-fluid-display-3);
50
+ /* Display heading measures. A typography role (data-ef-type, see
51
+ src/styles/foundations.css) lifts them for application screens. */
52
+ --ef-type-measure-h1: 14ch;
53
+ --ef-type-measure-h2: 18ch;
50
54
  --ef-type-leading-body: var(--ef-primitive-line-height-normal);
51
55
  --ef-type-leading-lead: var(--ef-primitive-line-height-normal);
52
56
  --ef-type-leading-heading: var(--ef-primitive-line-height-snug);
@@ -239,8 +243,8 @@
239
243
  line-height: var(--ef-type-leading-heading);
240
244
  }
241
245
 
242
- .ef-site :where(h1) { font-size: var(--ef-type-size-h1); max-inline-size: 14ch; }
243
- .ef-site :where(h2) { font-size: var(--ef-type-size-h2); max-inline-size: 18ch; }
246
+ .ef-site :where(h1) { font-size: var(--ef-type-size-h1); max-inline-size: var(--ef-type-measure-h1); }
247
+ .ef-site :where(h2) { font-size: var(--ef-type-size-h2); max-inline-size: var(--ef-type-measure-h2); }
244
248
  .ef-site :where(h3) { font-size: var(--ef-type-size-h3); line-height: var(--ef-type-leading-snug); }
245
249
  .ef-site :where(h4, h5, h6) { font-size: var(--ef-type-size-h4); line-height: var(--ef-type-leading-snug); }
246
250
 
package/dist/runtime.js CHANGED
@@ -52,6 +52,6 @@ export function registerEchelonRuntime(name, metadata, target = globalThis) {
52
52
  return installEchelonRuntimeRegistrar(target)?.(name, metadata);
53
53
  }
54
54
 
55
- export const FORMA_VERSION = "0.10.0";
55
+ export const FORMA_VERSION = "0.11.0";
56
56
 
57
57
  if (typeof window !== "undefined") registerEchelonRuntime("forma", { version: FORMA_VERSION }, window);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@echelon-foundry/design-system",
3
- "version": "0.10.0",
3
+ "version": "0.11.0-main.259.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Zero-component-runtime HTML and CSS design system for Echelon Foundry applications.",