domma-js 0.41.0 → 0.42.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-js",
3
- "version": "0.41.0",
3
+ "version": "0.42.0",
4
4
  "description": "Dynamic Object Manipulation & Modeling API - A complete front-end toolkit.",
5
5
  "main": "public/dist/domma.min.js",
6
6
  "module": "public/dist/domma.esm.js",
@@ -46,11 +46,12 @@
46
46
  "build:css": "node scripts/build-css.js",
47
47
  "validate:classes": "node scripts/validate-classes.js",
48
48
  "validate:theme": "node scripts/validate-theme-contrast.js",
49
+ "validate:contrast": "node scripts/validate-contrast-pairs.js",
49
50
  "validate:conventions": "node scripts/validate-conventions.js",
50
51
  "validate:showcase": "vitest run src/showcase-pages.test.js",
51
52
  "validate:showcase:strict": "SHOWCASE_STRICT=1 vitest run src/showcase-pages.test.js",
52
53
  "validate:showcase:baseline": "SHOWCASE_BASELINE=1 vitest run src/showcase-pages.test.js",
53
- "validate": "npm run validate:classes && npm run validate:theme && npm run validate:conventions",
54
+ "validate": "npm run validate:classes && npm run validate:theme && npm run validate:contrast && npm run validate:conventions",
54
55
  "build:css-bundles": "node scripts/build-css-bundles.js",
55
56
  "build:archives": "node scripts/build-archives.js",
56
57
  "build:kickstart-files": "node scripts/build-kickstart-files.js",
@@ -1,8 +1,8 @@
1
1
  /*!
2
- * Domma Complete CSS Bundle v0.41.0
2
+ * Domma Complete CSS Bundle v0.42.0
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-08-22T13:41:49.437Z
5
+ * Built: 2026-08-22T16:17:44.263Z
6
6
  */
7
7
 
8
8
  /* ============================================
@@ -11,11 +11,11 @@
11
11
  ============================================ */
12
12
 
13
13
  /*!
14
- * Domma Core CSS v0.41.0
14
+ * Domma Core CSS v0.42.0
15
15
  * Dynamic Object Manipulation & Modeling API
16
16
  * (c) 2026 Darryl Waterhouse & DCBW-IT
17
- * Built: 2026-08-22T13:41:49.294Z
18
- * Commit: 5d8b7e1
17
+ * Built: 2026-08-22T16:17:44.102Z
18
+ * Commit: 0f0475f
19
19
  */
20
20
 
21
21
  /**
@@ -4838,11 +4838,11 @@ body.dm-cloaked.dm-ready {
4838
4838
  ============================================ */
4839
4839
 
4840
4840
  /*!
4841
- * Domma Grid CSS v0.41.0
4841
+ * Domma Grid CSS v0.42.0
4842
4842
  * Dynamic Object Manipulation & Modeling API
4843
4843
  * (c) 2026 Darryl Waterhouse & DCBW-IT
4844
- * Built: 2026-08-22T13:41:49.299Z
4845
- * Commit: 5d8b7e1
4844
+ * Built: 2026-08-22T16:17:44.108Z
4845
+ * Commit: 0f0475f
4846
4846
  */
4847
4847
 
4848
4848
  /**
@@ -5463,11 +5463,11 @@ body.dm-cloaked.dm-ready {
5463
5463
  ============================================ */
5464
5464
 
5465
5465
  /*!
5466
- * Domma Elements CSS v0.41.0
5466
+ * Domma Elements CSS v0.42.0
5467
5467
  * Dynamic Object Manipulation & Modeling API
5468
5468
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5469
- * Built: 2026-08-22T13:41:49.303Z
5470
- * Commit: 5d8b7e1
5469
+ * Built: 2026-08-22T16:17:44.114Z
5470
+ * Commit: 0f0475f
5471
5471
  */
5472
5472
 
5473
5473
  /**
@@ -10800,7 +10800,9 @@ code {
10800
10800
  z-index: 1000;
10801
10801
  min-width: 10rem;
10802
10802
  padding: 0.5rem 0;
10803
- margin: 0.125rem 0 0;
10803
+ /* No margin: the menu is placed by JS from `offset`, and a margin here would
10804
+ silently add to it, so the box would not sit where it was measured to. */
10805
+ margin: 0;
10804
10806
  background-color: var(--dm-surface);
10805
10807
  border: 1px solid var(--dm-border);
10806
10808
  border-radius: var(--dm-radius-md);
@@ -10818,30 +10820,13 @@ code {
10818
10820
  }
10819
10821
 
10820
10822
  /*
10821
- * Hover bridge: the menu is rendered as a document.body sibling positioned with a
10822
- * small offset/margin gap from its trigger. On a hover-triggered dropdown that gap
10823
- * is a dead-zone - the pointer leaves the trigger before reaching the menu, firing
10824
- * the close. These transparent pseudo-elements extend the menu's hoverable area
10825
- * above and below it, so the trigger→menu path is one continuous hover surface.
10826
- * Only present on hover dropdowns, so click dropdowns are unaffected.
10823
+ * The trigger→menu gap is bridged in JS, not CSS. A transparent pseudo-element
10824
+ * strip used to sit above and below the menu to keep the hover path continuous,
10825
+ * but it only ever covered a fixed 12px directly in line with the menu box: any
10826
+ * `offset` larger than that, or an approach taken at an angle, fell outside it,
10827
+ * and while open it also blocked the page underneath. Dropdown._pointerInSafeZone()
10828
+ * does the same job geometrically - see src/elements.js.
10827
10829
  */
10828
- .domma-dropdown-menu-hover::before,
10829
- .domma-dropdown-menu-hover::after {
10830
- content: '';
10831
- position: absolute;
10832
- left: 0;
10833
- right: 0;
10834
- height: 0.75rem;
10835
- /* transparent - a hover surface only, never painted */
10836
- }
10837
-
10838
- .domma-dropdown-menu-hover::before {
10839
- bottom: 100%; /* bridges the gap when the menu opens below the trigger */
10840
- }
10841
-
10842
- .domma-dropdown-menu-hover::after {
10843
- top: 100%; /* bridges the gap when the menu opens above the trigger */
10844
- }
10845
10830
 
10846
10831
  .domma-dropdown-item {
10847
10832
  display: block;
@@ -13580,11 +13565,11 @@ code {
13580
13565
  ============================================ */
13581
13566
 
13582
13567
  /*!
13583
- * Domma Themes v0.41.0
13568
+ * Domma Themes v0.42.0
13584
13569
  * Dynamic Object Manipulation & Modeling API
13585
13570
  * (c) 2026 Darryl Waterhouse & DCBW-IT
13586
- * Built: 2026-08-22T13:41:49.280Z
13587
- * Commit: 5d8b7e1
13571
+ * Built: 2026-08-22T16:17:44.088Z
13572
+ * Commit: 0f0475f
13588
13573
  */
13589
13574
 
13590
13575
  /**
@@ -1,8 +1,8 @@
1
1
  /*!
2
- * Domma Data-Focused CSS Bundle v0.41.0
2
+ * Domma Data-Focused CSS Bundle v0.42.0
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-08-22T13:41:49.434Z
5
+ * Built: 2026-08-22T16:17:44.259Z
6
6
  */
7
7
 
8
8
  /* ============================================
@@ -11,11 +11,11 @@
11
11
  ============================================ */
12
12
 
13
13
  /*!
14
- * Domma Core CSS v0.41.0
14
+ * Domma Core CSS v0.42.0
15
15
  * Dynamic Object Manipulation & Modeling API
16
16
  * (c) 2026 Darryl Waterhouse & DCBW-IT
17
- * Built: 2026-08-22T13:41:49.294Z
18
- * Commit: 5d8b7e1
17
+ * Built: 2026-08-22T16:17:44.102Z
18
+ * Commit: 0f0475f
19
19
  */
20
20
 
21
21
  /**
@@ -4838,11 +4838,11 @@ body.dm-cloaked.dm-ready {
4838
4838
  ============================================ */
4839
4839
 
4840
4840
  /*!
4841
- * Domma Grid CSS v0.41.0
4841
+ * Domma Grid CSS v0.42.0
4842
4842
  * Dynamic Object Manipulation & Modeling API
4843
4843
  * (c) 2026 Darryl Waterhouse & DCBW-IT
4844
- * Built: 2026-08-22T13:41:49.299Z
4845
- * Commit: 5d8b7e1
4844
+ * Built: 2026-08-22T16:17:44.108Z
4845
+ * Commit: 0f0475f
4846
4846
  */
4847
4847
 
4848
4848
  /**
@@ -5463,11 +5463,11 @@ body.dm-cloaked.dm-ready {
5463
5463
  ============================================ */
5464
5464
 
5465
5465
  /*!
5466
- * Domma Elements CSS v0.41.0
5466
+ * Domma Elements CSS v0.42.0
5467
5467
  * Dynamic Object Manipulation & Modeling API
5468
5468
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5469
- * Built: 2026-08-22T13:41:49.303Z
5470
- * Commit: 5d8b7e1
5469
+ * Built: 2026-08-22T16:17:44.114Z
5470
+ * Commit: 0f0475f
5471
5471
  */
5472
5472
 
5473
5473
  /**
@@ -10800,7 +10800,9 @@ code {
10800
10800
  z-index: 1000;
10801
10801
  min-width: 10rem;
10802
10802
  padding: 0.5rem 0;
10803
- margin: 0.125rem 0 0;
10803
+ /* No margin: the menu is placed by JS from `offset`, and a margin here would
10804
+ silently add to it, so the box would not sit where it was measured to. */
10805
+ margin: 0;
10804
10806
  background-color: var(--dm-surface);
10805
10807
  border: 1px solid var(--dm-border);
10806
10808
  border-radius: var(--dm-radius-md);
@@ -10818,30 +10820,13 @@ code {
10818
10820
  }
10819
10821
 
10820
10822
  /*
10821
- * Hover bridge: the menu is rendered as a document.body sibling positioned with a
10822
- * small offset/margin gap from its trigger. On a hover-triggered dropdown that gap
10823
- * is a dead-zone - the pointer leaves the trigger before reaching the menu, firing
10824
- * the close. These transparent pseudo-elements extend the menu's hoverable area
10825
- * above and below it, so the trigger→menu path is one continuous hover surface.
10826
- * Only present on hover dropdowns, so click dropdowns are unaffected.
10823
+ * The trigger→menu gap is bridged in JS, not CSS. A transparent pseudo-element
10824
+ * strip used to sit above and below the menu to keep the hover path continuous,
10825
+ * but it only ever covered a fixed 12px directly in line with the menu box: any
10826
+ * `offset` larger than that, or an approach taken at an angle, fell outside it,
10827
+ * and while open it also blocked the page underneath. Dropdown._pointerInSafeZone()
10828
+ * does the same job geometrically - see src/elements.js.
10827
10829
  */
10828
- .domma-dropdown-menu-hover::before,
10829
- .domma-dropdown-menu-hover::after {
10830
- content: '';
10831
- position: absolute;
10832
- left: 0;
10833
- right: 0;
10834
- height: 0.75rem;
10835
- /* transparent - a hover surface only, never painted */
10836
- }
10837
-
10838
- .domma-dropdown-menu-hover::before {
10839
- bottom: 100%; /* bridges the gap when the menu opens below the trigger */
10840
- }
10841
-
10842
- .domma-dropdown-menu-hover::after {
10843
- top: 100%; /* bridges the gap when the menu opens above the trigger */
10844
- }
10845
10830
 
10846
10831
  .domma-dropdown-item {
10847
10832
  display: block;
@@ -13580,11 +13565,11 @@ code {
13580
13565
  ============================================ */
13581
13566
 
13582
13567
  /*!
13583
- * Domma Themes v0.41.0
13568
+ * Domma Themes v0.42.0
13584
13569
  * Dynamic Object Manipulation & Modeling API
13585
13570
  * (c) 2026 Darryl Waterhouse & DCBW-IT
13586
- * Built: 2026-08-22T13:41:49.280Z
13587
- * Commit: 5d8b7e1
13571
+ * Built: 2026-08-22T16:17:44.088Z
13572
+ * Commit: 0f0475f
13588
13573
  */
13589
13574
 
13590
13575
  /**
@@ -1,8 +1,8 @@
1
1
  /*!
2
- * Domma Essentials CSS Bundle v0.41.0
2
+ * Domma Essentials CSS Bundle v0.42.0
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-08-22T13:41:49.427Z
5
+ * Built: 2026-08-22T16:17:44.250Z
6
6
  */
7
7
 
8
8
  /* ============================================
@@ -11,11 +11,11 @@
11
11
  ============================================ */
12
12
 
13
13
  /*!
14
- * Domma Core CSS v0.41.0
14
+ * Domma Core CSS v0.42.0
15
15
  * Dynamic Object Manipulation & Modeling API
16
16
  * (c) 2026 Darryl Waterhouse & DCBW-IT
17
- * Built: 2026-08-22T13:41:49.294Z
18
- * Commit: 5d8b7e1
17
+ * Built: 2026-08-22T16:17:44.102Z
18
+ * Commit: 0f0475f
19
19
  */
20
20
 
21
21
  /**
@@ -4838,11 +4838,11 @@ body.dm-cloaked.dm-ready {
4838
4838
  ============================================ */
4839
4839
 
4840
4840
  /*!
4841
- * Domma Grid CSS v0.41.0
4841
+ * Domma Grid CSS v0.42.0
4842
4842
  * Dynamic Object Manipulation & Modeling API
4843
4843
  * (c) 2026 Darryl Waterhouse & DCBW-IT
4844
- * Built: 2026-08-22T13:41:49.299Z
4845
- * Commit: 5d8b7e1
4844
+ * Built: 2026-08-22T16:17:44.108Z
4845
+ * Commit: 0f0475f
4846
4846
  */
4847
4847
 
4848
4848
  /**
@@ -5463,11 +5463,11 @@ body.dm-cloaked.dm-ready {
5463
5463
  ============================================ */
5464
5464
 
5465
5465
  /*!
5466
- * Domma Elements CSS v0.41.0
5466
+ * Domma Elements CSS v0.42.0
5467
5467
  * Dynamic Object Manipulation & Modeling API
5468
5468
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5469
- * Built: 2026-08-22T13:41:49.303Z
5470
- * Commit: 5d8b7e1
5469
+ * Built: 2026-08-22T16:17:44.114Z
5470
+ * Commit: 0f0475f
5471
5471
  */
5472
5472
 
5473
5473
  /**
@@ -10800,7 +10800,9 @@ code {
10800
10800
  z-index: 1000;
10801
10801
  min-width: 10rem;
10802
10802
  padding: 0.5rem 0;
10803
- margin: 0.125rem 0 0;
10803
+ /* No margin: the menu is placed by JS from `offset`, and a margin here would
10804
+ silently add to it, so the box would not sit where it was measured to. */
10805
+ margin: 0;
10804
10806
  background-color: var(--dm-surface);
10805
10807
  border: 1px solid var(--dm-border);
10806
10808
  border-radius: var(--dm-radius-md);
@@ -10818,30 +10820,13 @@ code {
10818
10820
  }
10819
10821
 
10820
10822
  /*
10821
- * Hover bridge: the menu is rendered as a document.body sibling positioned with a
10822
- * small offset/margin gap from its trigger. On a hover-triggered dropdown that gap
10823
- * is a dead-zone - the pointer leaves the trigger before reaching the menu, firing
10824
- * the close. These transparent pseudo-elements extend the menu's hoverable area
10825
- * above and below it, so the trigger→menu path is one continuous hover surface.
10826
- * Only present on hover dropdowns, so click dropdowns are unaffected.
10823
+ * The trigger→menu gap is bridged in JS, not CSS. A transparent pseudo-element
10824
+ * strip used to sit above and below the menu to keep the hover path continuous,
10825
+ * but it only ever covered a fixed 12px directly in line with the menu box: any
10826
+ * `offset` larger than that, or an approach taken at an angle, fell outside it,
10827
+ * and while open it also blocked the page underneath. Dropdown._pointerInSafeZone()
10828
+ * does the same job geometrically - see src/elements.js.
10827
10829
  */
10828
- .domma-dropdown-menu-hover::before,
10829
- .domma-dropdown-menu-hover::after {
10830
- content: '';
10831
- position: absolute;
10832
- left: 0;
10833
- right: 0;
10834
- height: 0.75rem;
10835
- /* transparent - a hover surface only, never painted */
10836
- }
10837
-
10838
- .domma-dropdown-menu-hover::before {
10839
- bottom: 100%; /* bridges the gap when the menu opens below the trigger */
10840
- }
10841
-
10842
- .domma-dropdown-menu-hover::after {
10843
- top: 100%; /* bridges the gap when the menu opens above the trigger */
10844
- }
10845
10830
 
10846
10831
  .domma-dropdown-item {
10847
10832
  display: block;
@@ -13580,11 +13565,11 @@ code {
13580
13565
  ============================================ */
13581
13566
 
13582
13567
  /*!
13583
- * Domma Themes v0.41.0
13568
+ * Domma Themes v0.42.0
13584
13569
  * Dynamic Object Manipulation & Modeling API
13585
13570
  * (c) 2026 Darryl Waterhouse & DCBW-IT
13586
- * Built: 2026-08-22T13:41:49.280Z
13587
- * Commit: 5d8b7e1
13571
+ * Built: 2026-08-22T16:17:44.088Z
13572
+ * Commit: 0f0475f
13588
13573
  */
13589
13574
 
13590
13575
  /**
@@ -1,8 +1,8 @@
1
1
  /*!
2
- * Domma Full CSS Bundle v0.41.0
2
+ * Domma Full CSS Bundle v0.42.0
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-08-22T13:41:49.431Z
5
+ * Built: 2026-08-22T16:17:44.255Z
6
6
  */
7
7
 
8
8
  /* ============================================
@@ -11,11 +11,11 @@
11
11
  ============================================ */
12
12
 
13
13
  /*!
14
- * Domma Core CSS v0.41.0
14
+ * Domma Core CSS v0.42.0
15
15
  * Dynamic Object Manipulation & Modeling API
16
16
  * (c) 2026 Darryl Waterhouse & DCBW-IT
17
- * Built: 2026-08-22T13:41:49.294Z
18
- * Commit: 5d8b7e1
17
+ * Built: 2026-08-22T16:17:44.102Z
18
+ * Commit: 0f0475f
19
19
  */
20
20
 
21
21
  /**
@@ -4838,11 +4838,11 @@ body.dm-cloaked.dm-ready {
4838
4838
  ============================================ */
4839
4839
 
4840
4840
  /*!
4841
- * Domma Grid CSS v0.41.0
4841
+ * Domma Grid CSS v0.42.0
4842
4842
  * Dynamic Object Manipulation & Modeling API
4843
4843
  * (c) 2026 Darryl Waterhouse & DCBW-IT
4844
- * Built: 2026-08-22T13:41:49.299Z
4845
- * Commit: 5d8b7e1
4844
+ * Built: 2026-08-22T16:17:44.108Z
4845
+ * Commit: 0f0475f
4846
4846
  */
4847
4847
 
4848
4848
  /**
@@ -5463,11 +5463,11 @@ body.dm-cloaked.dm-ready {
5463
5463
  ============================================ */
5464
5464
 
5465
5465
  /*!
5466
- * Domma Elements CSS v0.41.0
5466
+ * Domma Elements CSS v0.42.0
5467
5467
  * Dynamic Object Manipulation & Modeling API
5468
5468
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5469
- * Built: 2026-08-22T13:41:49.303Z
5470
- * Commit: 5d8b7e1
5469
+ * Built: 2026-08-22T16:17:44.114Z
5470
+ * Commit: 0f0475f
5471
5471
  */
5472
5472
 
5473
5473
  /**
@@ -10800,7 +10800,9 @@ code {
10800
10800
  z-index: 1000;
10801
10801
  min-width: 10rem;
10802
10802
  padding: 0.5rem 0;
10803
- margin: 0.125rem 0 0;
10803
+ /* No margin: the menu is placed by JS from `offset`, and a margin here would
10804
+ silently add to it, so the box would not sit where it was measured to. */
10805
+ margin: 0;
10804
10806
  background-color: var(--dm-surface);
10805
10807
  border: 1px solid var(--dm-border);
10806
10808
  border-radius: var(--dm-radius-md);
@@ -10818,30 +10820,13 @@ code {
10818
10820
  }
10819
10821
 
10820
10822
  /*
10821
- * Hover bridge: the menu is rendered as a document.body sibling positioned with a
10822
- * small offset/margin gap from its trigger. On a hover-triggered dropdown that gap
10823
- * is a dead-zone - the pointer leaves the trigger before reaching the menu, firing
10824
- * the close. These transparent pseudo-elements extend the menu's hoverable area
10825
- * above and below it, so the trigger→menu path is one continuous hover surface.
10826
- * Only present on hover dropdowns, so click dropdowns are unaffected.
10823
+ * The trigger→menu gap is bridged in JS, not CSS. A transparent pseudo-element
10824
+ * strip used to sit above and below the menu to keep the hover path continuous,
10825
+ * but it only ever covered a fixed 12px directly in line with the menu box: any
10826
+ * `offset` larger than that, or an approach taken at an angle, fell outside it,
10827
+ * and while open it also blocked the page underneath. Dropdown._pointerInSafeZone()
10828
+ * does the same job geometrically - see src/elements.js.
10827
10829
  */
10828
- .domma-dropdown-menu-hover::before,
10829
- .domma-dropdown-menu-hover::after {
10830
- content: '';
10831
- position: absolute;
10832
- left: 0;
10833
- right: 0;
10834
- height: 0.75rem;
10835
- /* transparent - a hover surface only, never painted */
10836
- }
10837
-
10838
- .domma-dropdown-menu-hover::before {
10839
- bottom: 100%; /* bridges the gap when the menu opens below the trigger */
10840
- }
10841
-
10842
- .domma-dropdown-menu-hover::after {
10843
- top: 100%; /* bridges the gap when the menu opens above the trigger */
10844
- }
10845
10830
 
10846
10831
  .domma-dropdown-item {
10847
10832
  display: block;
@@ -13580,11 +13565,11 @@ code {
13580
13565
  ============================================ */
13581
13566
 
13582
13567
  /*!
13583
- * Domma Themes v0.41.0
13568
+ * Domma Themes v0.42.0
13584
13569
  * Dynamic Object Manipulation & Modeling API
13585
13570
  * (c) 2026 Darryl Waterhouse & DCBW-IT
13586
- * Built: 2026-08-22T13:41:49.280Z
13587
- * Commit: 5d8b7e1
13571
+ * Built: 2026-08-22T16:17:44.088Z
13572
+ * Commit: 0f0475f
13588
13573
  */
13589
13574
 
13590
13575
  /**
@@ -1,8 +1,8 @@
1
1
  /*!
2
- * Domma Minimal CSS Bundle v0.41.0
2
+ * Domma Minimal CSS Bundle v0.42.0
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-08-22T13:41:49.426Z
5
+ * Built: 2026-08-22T16:17:44.248Z
6
6
  */
7
7
 
8
8
  /* ============================================
@@ -11,11 +11,11 @@
11
11
  ============================================ */
12
12
 
13
13
  /*!
14
- * Domma Core CSS v0.41.0
14
+ * Domma Core CSS v0.42.0
15
15
  * Dynamic Object Manipulation & Modeling API
16
16
  * (c) 2026 Darryl Waterhouse & DCBW-IT
17
- * Built: 2026-08-22T13:41:49.294Z
18
- * Commit: 5d8b7e1
17
+ * Built: 2026-08-22T16:17:44.102Z
18
+ * Commit: 0f0475f
19
19
  */
20
20
 
21
21
  /**
@@ -4838,11 +4838,11 @@ body.dm-cloaked.dm-ready {
4838
4838
  ============================================ */
4839
4839
 
4840
4840
  /*!
4841
- * Domma Grid CSS v0.41.0
4841
+ * Domma Grid CSS v0.42.0
4842
4842
  * Dynamic Object Manipulation & Modeling API
4843
4843
  * (c) 2026 Darryl Waterhouse & DCBW-IT
4844
- * Built: 2026-08-22T13:41:49.299Z
4845
- * Commit: 5d8b7e1
4844
+ * Built: 2026-08-22T16:17:44.108Z
4845
+ * Commit: 0f0475f
4846
4846
  */
4847
4847
 
4848
4848
  /**
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * Domma Flags v0.41.0
2
+ * Domma Flags v0.42.0
3
3
  * Nation flags as inline SVG (opt-in module)
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-08-22T13:41:39.994Z
6
- * Commit: 5d8b7e1
5
+ * Built: 2026-08-22T16:17:34.767Z
6
+ * Commit: 0f0475f
7
7
  *
8
8
  * Requires: domma.min.js
9
9
  */
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * Domma Flags v0.41.0
2
+ * Domma Flags v0.42.0
3
3
  * Nation flags as inline SVG (opt-in module)
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-08-22T13:41:39.994Z
6
- * Commit: 5d8b7e1
5
+ * Built: 2026-08-22T16:17:34.767Z
6
+ * Commit: 0f0475f
7
7
  *
8
8
  * Requires: domma.min.js
9
9
  */
@@ -1,8 +1,8 @@
1
1
  /*!
2
- * Domma Syntax Highlighter v0.41.0
2
+ * Domma Syntax Highlighter v0.42.0
3
3
  * Lightweight code syntax highlighting for JavaScript, HTML, and CSS
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-08-22T13:41:39.989Z
6
- * Commit: 5d8b7e1
5
+ * Built: 2026-08-22T16:17:34.763Z
6
+ * Commit: 0f0475f
7
7
  */
8
8
  !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).DommaSyntax={})}(this,function(t){"use strict";const e={javascript:[{type:"comment",pattern:/\/\*[\s\S]*?\*\//g},{type:"comment",pattern:/\/\/.*/g},{type:"template-string",pattern:/`(?:\\.|[^`\\])*`/g},{type:"string",pattern:/"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g},{type:"keyword",pattern:/\b(const|let|var|function|return|if|else|for|while|do|break|continue|switch|case|default|try|catch|finally|throw|async|await|class|extends|static|new|this|super|import|export|from|as|default|yield|typeof|instanceof|in|of|delete|void)\b/g},{type:"boolean",pattern:/\b(true|false|null|undefined|NaN|Infinity)\b/g},{type:"number",pattern:/\b\d+\.?\d*([eE][+-]?\d+)?\b/g},{type:"function",pattern:/\b([a-zA-Z_$][\w$]*)\s*(?=\()/g},{type:"class-name",pattern:/\b[A-Z][\w$]*\b/g},{type:"operator",pattern:/[+\-*/%=<>!&|^~?:]+|===|!==|==|!=|<=|>=|&&|\|\||<<|>>|>>>/g},{type:"punctuation",pattern:/[{}[\]();,.]/g}],html:[{type:"comment",pattern:/<!--[\s\S]*?-->/g},{type:"doctype",pattern:/<!DOCTYPE[^>]*>/gi},{type:"tag-open",pattern:/<\/?[a-zA-Z][\w-]*/g},{type:"tag-close",pattern:/\/?>/g},{type:"attr-name",pattern:/\s+[a-zA-Z:@][\w:.-]*(?=\s*=)/g},{type:"attr-value",pattern:/=\s*"[^"]*"|=\s*'[^']*'/g},{type:"entity",pattern:/&[#\w]+;/g}],css:[{type:"comment",pattern:/\/\*[\s\S]*?\*\//g},{type:"at-rule",pattern:/@[\w-]+/g},{type:"selector",pattern:/[.#]?[a-zA-Z][\w-]*(?=\s*[{,])/g},{type:"property",pattern:/\b[\w-]+(?=\s*:)/g},{type:"string",pattern:/"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g},{type:"function",pattern:/\b[\w-]+(?=\()/g},{type:"important",pattern:/!important\b/g},{type:"number",pattern:/\b\d+\.?\d*(px|em|rem|%|vh|vw|pt|cm|mm|in|pc|ex|ch|vmin|vmax|fr)?\b/g},{type:"color",pattern:/#[\da-fA-F]{3,8}\b/g},{type:"punctuation",pattern:/[{}:;,()]/g}]};function n(t){const e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return t.replace(/[&<>"']/g,t=>e[t])}class a{constructor(){this.config={autoDetect:!0,preserveOriginal:!0,selector:".code-block",showLanguageBadge:!1,languagePrefix:"language-"}}highlight(t,a=null){const r="string"==typeof t?document.querySelector(t):t;if(!r||r.hasAttribute("data-syntax-highlighted"))return!1;if(!a&&this.config.autoDetect){const t=Array.from(r.classList).find(t=>t.startsWith(this.config.languagePrefix));t&&(a=t.substring(this.config.languagePrefix.length))}if(!a||!e[a])return!1;const o=r.textContent||"";this.config.preserveOriginal&&r.setAttribute("data-original-code",o);const i=function(t,a){const r=e[a];if(!r)return n(t);const o=[];for(const{type:e,pattern:n}of r){if("html"===a&&"entity"===e)continue;let r;for(n.lastIndex=0;null!==(r=n.exec(t));)o.push({start:r.index,end:r.index+r[0].length,text:r[0],type:e})}o.sort((t,e)=>t.start-e.start);const i=[];let s=0;for(const t of o)t.start>=s&&(i.push(t),s=t.end);let c="",p=0;for(const e of i)e.start>p&&(c+=n(t.substring(p,e.start))),c+=`<span class="syntax-${e.type}">${n(e.text)}</span>`,p=e.end;return p<t.length&&(c+=n(t.substring(p))),c}(o,a);return r.innerHTML=i,r.setAttribute("data-syntax-highlighted","true"),r.setAttribute("data-language",a),this.config.showLanguageBadge&&this.addLanguageBadge(r,a),!0}scan(t={}){const e=t.selector||this.config.selector,n=document.querySelectorAll(e);let a=0;return n.forEach(e=>{this.highlight(e,t.language||null)&&(this.addCopyButton(e),a++)}),a}register(t,n){t&&Array.isArray(n)?e[t]=n:console.error("SyntaxHighlighter: Invalid language registration")}configure(t){return t?(Object.assign(this.config,t),this.config):{...this.config}}addLanguageBadge(t,e){if(t.querySelector(".syntax-language-badge"))return;const n=document.createElement("div");n.className="syntax-language-badge",n.textContent=e.toUpperCase(),t.style.position="relative",t.insertBefore(n,t.firstChild)}getLanguages(){return Object.keys(e)}isLanguageSupported(t){return t in e}addCopyButton(t){if(t.parentElement&&t.parentElement.classList.contains("code-block-wrapper"))return;const e=document.createElement("div");e.className="code-block-wrapper";const n=document.createElement("button");n.className="code-block-copy",n.setAttribute("aria-label","Copy code to clipboard"),n.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>',n.addEventListener("click",async()=>{const e=t.getAttribute("data-original-code")||t.textContent;try{if(navigator.clipboard&&navigator.clipboard.writeText)await navigator.clipboard.writeText(e);else{const t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)}n.classList.add("copied"),n.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"></polyline></svg>',setTimeout(()=>{n.classList.remove("copied"),n.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>'},2e3)}catch(t){console.error("Failed to copy code:",t)}}),t.parentNode.insertBefore(e,t),e.appendChild(t),e.appendChild(n)}}const r=new a;"undefined"!=typeof document&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{r.scan()}):setTimeout(()=>r.scan(),0)),"undefined"!=typeof window&&(window.Domma&&(window.Domma.syntax=r),window.DommaSyntax=r),t.LANGUAGES=e,t.SyntaxHighlighter=a,t.default=r,t.syntax=r,Object.defineProperty(t,"__esModule",{value:!0})});
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * Domma Core CSS v0.41.0
2
+ * Domma Core CSS v0.42.0
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-08-22T13:41:49.294Z
6
- * Commit: 5d8b7e1
5
+ * Built: 2026-08-22T16:17:44.102Z
6
+ * Commit: 0f0475f
7
7
  */
8
8
 
9
9
  /**