domma-js 0.27.1 → 0.27.3

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.
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Domma Flags Module - TypeScript Declarations
3
+ * Nation flags as inline SVG, keyed by ISO 3166-1 alpha-2 code.
4
+ *
5
+ * Opt-in module: load domma-flags.min.js after domma.min.js.
6
+ * Exposes the FL global and Domma.flags / Domma.FL.
7
+ */
8
+
9
+ export type FlagRegion = 'europe' | 'americas' | 'africa' | 'asia' | 'oceania' | string;
10
+
11
+ export type FlagShape = 'rect' | 'rounded' | 'square' | 'circle';
12
+
13
+ /** A single overlay primitive used to compose a flag. */
14
+ export interface FlagOverlay {
15
+ type: 'rect' | 'circle' | 'ellipse' | 'line' | 'path' | 'star' | 'crescent' | 'group';
16
+ fill?: string;
17
+ stroke?: string;
18
+ strokeWidth?: number;
19
+ [key: string]: unknown;
20
+ }
21
+
22
+ /** A flag definition — either raw SVG markup or a compact descriptor. */
23
+ export interface FlagDefinition {
24
+ /** Country name */
25
+ name: string;
26
+ /** Region group (defaults to 'custom' when registered) */
27
+ region?: FlagRegion;
28
+ /** Raw inner SVG markup (60×40 canvas) */
29
+ svg?: string;
30
+ /** Solid background colour */
31
+ bg?: string;
32
+ /** Stripe descriptor */
33
+ stripes?: {
34
+ dir?: 'h' | 'v';
35
+ colors: string[];
36
+ weights?: number[];
37
+ };
38
+ /** Nordic (offset) cross descriptor */
39
+ cross?: {
40
+ bg: string;
41
+ colour: string;
42
+ border?: string;
43
+ thickness?: number;
44
+ };
45
+ /** Overlay primitives drawn on top */
46
+ overlays?: FlagOverlay[];
47
+ }
48
+
49
+ /** Options for rendering a flag. */
50
+ export interface FlagRenderOptions {
51
+ /** Height in px; width follows the 3:2 aspect (default 24) */
52
+ size?: number;
53
+ /** Explicit width override */
54
+ width?: number;
55
+ /** Explicit height override */
56
+ height?: number;
57
+ /** Output shape (default 'rect') */
58
+ shape?: FlagShape;
59
+ /** Add a hairline border; pass a colour string to customise */
60
+ border?: boolean | string;
61
+ /** Extra CSS classes */
62
+ class?: string;
63
+ /** Accessible title (defaults to the country name) */
64
+ title?: string;
65
+ /** Additional SVG attributes */
66
+ attrs?: Record<string, string>;
67
+ }
68
+
69
+ export interface FlagInjectOptions extends FlagRenderOptions {
70
+ /** Where to place the flag relative to the target (default 'prepend') */
71
+ position?: 'prepend' | 'append' | 'replace';
72
+ }
73
+
74
+ export interface FlagRegionMeta {
75
+ name: string;
76
+ description?: string;
77
+ codes: string[];
78
+ }
79
+
80
+ /** The flag registry (FL / Domma.flags). */
81
+ export interface Flags {
82
+ /** Render a flag as an SVG element. */
83
+ render(code: string, options?: FlagRenderOptions): SVGElement | null;
84
+
85
+ /** Get a flag as an HTML string. */
86
+ html(code: string, options?: FlagRenderOptions): string;
87
+
88
+ /** Inject a flag into a target element or selector. */
89
+ inject(target: string | HTMLElement, code: string, options?: FlagInjectOptions): SVGElement | null;
90
+
91
+ /** Replace all [data-flag] elements within a container with SVGs. */
92
+ scan(container?: HTMLElement | string): number;
93
+
94
+ /** Register (or override) a flag. */
95
+ register(code: string, definition: FlagDefinition): Flags;
96
+
97
+ /** Remove a registered flag. */
98
+ unregister(code: string): boolean;
99
+
100
+ /** Whether a flag exists. */
101
+ has(code: string): boolean;
102
+
103
+ /** Get a flag definition. */
104
+ get(code: string): FlagDefinition | null;
105
+
106
+ /** Get the country name for a code. */
107
+ name(code: string): string | null;
108
+
109
+ /** List flag codes, optionally filtered by region. */
110
+ list(region?: FlagRegion): string[];
111
+
112
+ /** List all regions with metadata. */
113
+ listRegions(): Record<string, FlagRegionMeta>;
114
+
115
+ /** Total number of flags. */
116
+ count(): number;
117
+
118
+ /** Search flags by code or country name. */
119
+ search(query: string): string[];
120
+ }
121
+
122
+ export const flags: Flags;
123
+
124
+ declare global {
125
+ /**
126
+ * FL - Domma Flags (opt-in module)
127
+ * Nation flags as inline SVG, keyed by ISO 3166-1 alpha-2 code.
128
+ */
129
+ const FL: Flags;
130
+ }
@@ -18,6 +18,7 @@ export * from './storage';
18
18
  export * from './http';
19
19
  export * from './theme';
20
20
  export * from './icons';
21
+ export * from './flags';
21
22
 
22
23
  // Import types for the main Domma object
23
24
  import {dom, DommaCollection} from './dom';
@@ -31,6 +32,7 @@ import {Storage, storage} from './storage';
31
32
  import {Http, http} from './http';
32
33
  import {Theme, theme} from './theme';
33
34
  import {Icons, icons} from './icons';
35
+ import {Flags} from './flags';
34
36
 
35
37
  // ============================================
36
38
  // Main Domma Interface
@@ -81,6 +83,12 @@ export interface DommaStatic {
81
83
  /** Icon library */
82
84
  icons: Icons;
83
85
 
86
+ /** Nation flags (opt-in module — present when domma-flags is loaded) */
87
+ flags?: Flags;
88
+
89
+ /** Alias for {@link DommaStatic.flags} (opt-in module) */
90
+ FL?: Flags;
91
+
84
92
  // ============================================
85
93
  // ConfigEngine Methods ($.setup, $.config, etc.)
86
94
  // ============================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-js",
3
- "version": "0.27.1",
3
+ "version": "0.27.3",
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",
@@ -22,6 +22,8 @@
22
22
  "public/dist/grid.css",
23
23
  "public/dist/syntax.css",
24
24
  "public/dist/domma-syntax.min.js",
25
+ "public/dist/domma-flags.min.js",
26
+ "public/dist/domma-flags.esm.js",
25
27
  "public/dist/themes/",
26
28
  "assets/types/",
27
29
  "LICENSE",
@@ -1,8 +1,8 @@
1
1
  /*!
2
- * Domma Complete CSS Bundle v0.27.1
2
+ * Domma Complete CSS Bundle v0.27.3
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-05-30T10:04:08.205Z
5
+ * Built: 2026-06-13T07:03:29.838Z
6
6
  */
7
7
 
8
8
  /* ============================================
@@ -11,11 +11,11 @@
11
11
  ============================================ */
12
12
 
13
13
  /*!
14
- * Domma Core CSS v0.27.1
14
+ * Domma Core CSS v0.27.3
15
15
  * Dynamic Object Manipulation & Modeling API
16
16
  * (c) 2026 Darryl Waterhouse & DCBW-IT
17
- * Built: 2026-05-30T10:04:07.988Z
18
- * Commit: 0c4c061
17
+ * Built: 2026-06-13T07:03:29.622Z
18
+ * Commit: 8b31341
19
19
  */
20
20
 
21
21
  /**
@@ -4829,11 +4829,11 @@ body.dm-cloaked.dm-ready {
4829
4829
  ============================================ */
4830
4830
 
4831
4831
  /*!
4832
- * Domma Grid CSS v0.27.1
4832
+ * Domma Grid CSS v0.27.3
4833
4833
  * Dynamic Object Manipulation & Modeling API
4834
4834
  * (c) 2026 Darryl Waterhouse & DCBW-IT
4835
- * Built: 2026-05-30T10:04:07.992Z
4836
- * Commit: 0c4c061
4835
+ * Built: 2026-06-13T07:03:29.627Z
4836
+ * Commit: 8b31341
4837
4837
  */
4838
4838
 
4839
4839
  /**
@@ -5454,11 +5454,11 @@ body.dm-cloaked.dm-ready {
5454
5454
  ============================================ */
5455
5455
 
5456
5456
  /*!
5457
- * Domma Elements CSS v0.27.1
5457
+ * Domma Elements CSS v0.27.3
5458
5458
  * Dynamic Object Manipulation & Modeling API
5459
5459
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5460
- * Built: 2026-05-30T10:04:07.998Z
5461
- * Commit: 0c4c061
5460
+ * Built: 2026-06-13T07:03:29.632Z
5461
+ * Commit: 8b31341
5462
5462
  */
5463
5463
 
5464
5464
  /**
@@ -7918,7 +7918,7 @@ code {
7918
7918
  transition: transform 0.2s ease;
7919
7919
  }
7920
7920
 
7921
- .navbar-dropdown.open .navbar-caret {
7921
+ .navbar-dropdown.open > .navbar-dropdown-toggle:not(.navbar-submenu-toggle) .navbar-caret {
7922
7922
  transform: rotate(180deg);
7923
7923
  }
7924
7924
 
@@ -7938,7 +7938,7 @@ code {
7938
7938
  z-index: var(--dm-z-dropdown, 1000);
7939
7939
  }
7940
7940
 
7941
- .navbar-dropdown.open .navbar-dropdown-menu {
7941
+ .navbar-dropdown.open > .navbar-dropdown-menu {
7942
7942
  display: block;
7943
7943
  }
7944
7944
 
@@ -7995,6 +7995,89 @@ code {
7995
7995
  background: var(--dm-surface);
7996
7996
  }
7997
7997
 
7998
+ /* ============================================
7999
+ NAVBAR - NESTED (MULTI-LEVEL) DROPDOWNS
8000
+ ============================================ */
8001
+
8002
+ .navbar-dropdown-sub {
8003
+ position: relative;
8004
+ }
8005
+
8006
+ /* A submenu toggle looks like a dropdown item but opens a nested menu */
8007
+ .navbar-submenu-toggle {
8008
+ display: flex;
8009
+ align-items: center;
8010
+ justify-content: space-between;
8011
+ gap: 0.5rem;
8012
+ width: 100%;
8013
+ padding: 0.5rem 1rem;
8014
+ background: none;
8015
+ border: none;
8016
+ cursor: pointer;
8017
+ font: inherit;
8018
+ font-size: var(--dm-font-size-sm);
8019
+ color: var(--dm-text, #212529);
8020
+ text-align: left;
8021
+ text-decoration: none;
8022
+ }
8023
+
8024
+ .navbar-submenu-toggle:hover {
8025
+ background: var(--dm-hover-bg, rgba(0, 0, 0, 0.05));
8026
+ }
8027
+
8028
+ .navbar-light .navbar-submenu-toggle:hover,
8029
+ [data-mode="light"] .navbar-submenu-toggle:hover {
8030
+ background: #1e293b !important;
8031
+ color: #ffffff !important;
8032
+ border-radius: var(--dm-radius-md);
8033
+ }
8034
+
8035
+ .navbar-dark .navbar-submenu-toggle {
8036
+ color: var(--dm-gray-400, #adb5bd);
8037
+ }
8038
+
8039
+ .navbar-dark .navbar-submenu-toggle:hover {
8040
+ background: rgba(255, 255, 255, 0.3);
8041
+ color: var(--dm-text-inverse, var(--dm-white));
8042
+ }
8043
+
8044
+ /* Submenu caret points to the side to signal a fly-out */
8045
+ .navbar-submenu-toggle .navbar-caret {
8046
+ transform: rotate(-90deg);
8047
+ margin-left: auto;
8048
+ }
8049
+
8050
+ /* The nested menu flies out to the right of its parent entry (desktop) */
8051
+ .navbar-dropdown-submenu {
8052
+ top: 0;
8053
+ left: 100%;
8054
+ margin: 0 0 0 0.25rem;
8055
+ }
8056
+
8057
+ .navbar-dark .navbar-dropdown-submenu {
8058
+ background: var(--dm-surface);
8059
+ border-color: var(--dm-border-dark, var(--dm-border));
8060
+ }
8061
+
8062
+ /* On mobile the nested menu stacks and indents instead of flying out */
8063
+ @media (max-width: 992px) {
8064
+ .navbar-dropdown-submenu {
8065
+ position: static;
8066
+ left: auto;
8067
+ margin: 0;
8068
+ min-width: 0;
8069
+ padding: 0 0 0 0.75rem;
8070
+ border: none;
8071
+ border-left: 1px solid var(--dm-border, #dee2e6);
8072
+ border-radius: 0;
8073
+ box-shadow: none;
8074
+ }
8075
+
8076
+ .navbar-submenu-toggle .navbar-caret {
8077
+ transform: rotate(0deg);
8078
+ }
8079
+ }
8080
+
7998
8081
  /* Pill button styles (for Download button) */
7999
8082
  .pill {
8000
8083
  display: inline-block;
@@ -13317,11 +13400,11 @@ code {
13317
13400
  ============================================ */
13318
13401
 
13319
13402
  /*!
13320
- * Domma Themes v0.27.1
13403
+ * Domma Themes v0.27.3
13321
13404
  * Dynamic Object Manipulation & Modeling API
13322
13405
  * (c) 2026 Darryl Waterhouse & DCBW-IT
13323
- * Built: 2026-05-30T10:04:07.972Z
13324
- * Commit: 0c4c061
13406
+ * Built: 2026-06-13T07:03:29.606Z
13407
+ * Commit: 8b31341
13325
13408
  */
13326
13409
 
13327
13410
  /**
@@ -1,8 +1,8 @@
1
1
  /*!
2
- * Domma Data-Focused CSS Bundle v0.27.1
2
+ * Domma Data-Focused CSS Bundle v0.27.3
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-05-30T10:04:08.200Z
5
+ * Built: 2026-06-13T07:03:29.832Z
6
6
  */
7
7
 
8
8
  /* ============================================
@@ -11,11 +11,11 @@
11
11
  ============================================ */
12
12
 
13
13
  /*!
14
- * Domma Core CSS v0.27.1
14
+ * Domma Core CSS v0.27.3
15
15
  * Dynamic Object Manipulation & Modeling API
16
16
  * (c) 2026 Darryl Waterhouse & DCBW-IT
17
- * Built: 2026-05-30T10:04:07.988Z
18
- * Commit: 0c4c061
17
+ * Built: 2026-06-13T07:03:29.622Z
18
+ * Commit: 8b31341
19
19
  */
20
20
 
21
21
  /**
@@ -4829,11 +4829,11 @@ body.dm-cloaked.dm-ready {
4829
4829
  ============================================ */
4830
4830
 
4831
4831
  /*!
4832
- * Domma Grid CSS v0.27.1
4832
+ * Domma Grid CSS v0.27.3
4833
4833
  * Dynamic Object Manipulation & Modeling API
4834
4834
  * (c) 2026 Darryl Waterhouse & DCBW-IT
4835
- * Built: 2026-05-30T10:04:07.992Z
4836
- * Commit: 0c4c061
4835
+ * Built: 2026-06-13T07:03:29.627Z
4836
+ * Commit: 8b31341
4837
4837
  */
4838
4838
 
4839
4839
  /**
@@ -5454,11 +5454,11 @@ body.dm-cloaked.dm-ready {
5454
5454
  ============================================ */
5455
5455
 
5456
5456
  /*!
5457
- * Domma Elements CSS v0.27.1
5457
+ * Domma Elements CSS v0.27.3
5458
5458
  * Dynamic Object Manipulation & Modeling API
5459
5459
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5460
- * Built: 2026-05-30T10:04:07.998Z
5461
- * Commit: 0c4c061
5460
+ * Built: 2026-06-13T07:03:29.632Z
5461
+ * Commit: 8b31341
5462
5462
  */
5463
5463
 
5464
5464
  /**
@@ -7918,7 +7918,7 @@ code {
7918
7918
  transition: transform 0.2s ease;
7919
7919
  }
7920
7920
 
7921
- .navbar-dropdown.open .navbar-caret {
7921
+ .navbar-dropdown.open > .navbar-dropdown-toggle:not(.navbar-submenu-toggle) .navbar-caret {
7922
7922
  transform: rotate(180deg);
7923
7923
  }
7924
7924
 
@@ -7938,7 +7938,7 @@ code {
7938
7938
  z-index: var(--dm-z-dropdown, 1000);
7939
7939
  }
7940
7940
 
7941
- .navbar-dropdown.open .navbar-dropdown-menu {
7941
+ .navbar-dropdown.open > .navbar-dropdown-menu {
7942
7942
  display: block;
7943
7943
  }
7944
7944
 
@@ -7995,6 +7995,89 @@ code {
7995
7995
  background: var(--dm-surface);
7996
7996
  }
7997
7997
 
7998
+ /* ============================================
7999
+ NAVBAR - NESTED (MULTI-LEVEL) DROPDOWNS
8000
+ ============================================ */
8001
+
8002
+ .navbar-dropdown-sub {
8003
+ position: relative;
8004
+ }
8005
+
8006
+ /* A submenu toggle looks like a dropdown item but opens a nested menu */
8007
+ .navbar-submenu-toggle {
8008
+ display: flex;
8009
+ align-items: center;
8010
+ justify-content: space-between;
8011
+ gap: 0.5rem;
8012
+ width: 100%;
8013
+ padding: 0.5rem 1rem;
8014
+ background: none;
8015
+ border: none;
8016
+ cursor: pointer;
8017
+ font: inherit;
8018
+ font-size: var(--dm-font-size-sm);
8019
+ color: var(--dm-text, #212529);
8020
+ text-align: left;
8021
+ text-decoration: none;
8022
+ }
8023
+
8024
+ .navbar-submenu-toggle:hover {
8025
+ background: var(--dm-hover-bg, rgba(0, 0, 0, 0.05));
8026
+ }
8027
+
8028
+ .navbar-light .navbar-submenu-toggle:hover,
8029
+ [data-mode="light"] .navbar-submenu-toggle:hover {
8030
+ background: #1e293b !important;
8031
+ color: #ffffff !important;
8032
+ border-radius: var(--dm-radius-md);
8033
+ }
8034
+
8035
+ .navbar-dark .navbar-submenu-toggle {
8036
+ color: var(--dm-gray-400, #adb5bd);
8037
+ }
8038
+
8039
+ .navbar-dark .navbar-submenu-toggle:hover {
8040
+ background: rgba(255, 255, 255, 0.3);
8041
+ color: var(--dm-text-inverse, var(--dm-white));
8042
+ }
8043
+
8044
+ /* Submenu caret points to the side to signal a fly-out */
8045
+ .navbar-submenu-toggle .navbar-caret {
8046
+ transform: rotate(-90deg);
8047
+ margin-left: auto;
8048
+ }
8049
+
8050
+ /* The nested menu flies out to the right of its parent entry (desktop) */
8051
+ .navbar-dropdown-submenu {
8052
+ top: 0;
8053
+ left: 100%;
8054
+ margin: 0 0 0 0.25rem;
8055
+ }
8056
+
8057
+ .navbar-dark .navbar-dropdown-submenu {
8058
+ background: var(--dm-surface);
8059
+ border-color: var(--dm-border-dark, var(--dm-border));
8060
+ }
8061
+
8062
+ /* On mobile the nested menu stacks and indents instead of flying out */
8063
+ @media (max-width: 992px) {
8064
+ .navbar-dropdown-submenu {
8065
+ position: static;
8066
+ left: auto;
8067
+ margin: 0;
8068
+ min-width: 0;
8069
+ padding: 0 0 0 0.75rem;
8070
+ border: none;
8071
+ border-left: 1px solid var(--dm-border, #dee2e6);
8072
+ border-radius: 0;
8073
+ box-shadow: none;
8074
+ }
8075
+
8076
+ .navbar-submenu-toggle .navbar-caret {
8077
+ transform: rotate(0deg);
8078
+ }
8079
+ }
8080
+
7998
8081
  /* Pill button styles (for Download button) */
7999
8082
  .pill {
8000
8083
  display: inline-block;
@@ -13317,11 +13400,11 @@ code {
13317
13400
  ============================================ */
13318
13401
 
13319
13402
  /*!
13320
- * Domma Themes v0.27.1
13403
+ * Domma Themes v0.27.3
13321
13404
  * Dynamic Object Manipulation & Modeling API
13322
13405
  * (c) 2026 Darryl Waterhouse & DCBW-IT
13323
- * Built: 2026-05-30T10:04:07.972Z
13324
- * Commit: 0c4c061
13406
+ * Built: 2026-06-13T07:03:29.606Z
13407
+ * Commit: 8b31341
13325
13408
  */
13326
13409
 
13327
13410
  /**
@@ -1,8 +1,8 @@
1
1
  /*!
2
- * Domma Essentials CSS Bundle v0.27.1
2
+ * Domma Essentials CSS Bundle v0.27.3
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-05-30T10:04:08.189Z
5
+ * Built: 2026-06-13T07:03:29.821Z
6
6
  */
7
7
 
8
8
  /* ============================================
@@ -11,11 +11,11 @@
11
11
  ============================================ */
12
12
 
13
13
  /*!
14
- * Domma Core CSS v0.27.1
14
+ * Domma Core CSS v0.27.3
15
15
  * Dynamic Object Manipulation & Modeling API
16
16
  * (c) 2026 Darryl Waterhouse & DCBW-IT
17
- * Built: 2026-05-30T10:04:07.988Z
18
- * Commit: 0c4c061
17
+ * Built: 2026-06-13T07:03:29.622Z
18
+ * Commit: 8b31341
19
19
  */
20
20
 
21
21
  /**
@@ -4829,11 +4829,11 @@ body.dm-cloaked.dm-ready {
4829
4829
  ============================================ */
4830
4830
 
4831
4831
  /*!
4832
- * Domma Grid CSS v0.27.1
4832
+ * Domma Grid CSS v0.27.3
4833
4833
  * Dynamic Object Manipulation & Modeling API
4834
4834
  * (c) 2026 Darryl Waterhouse & DCBW-IT
4835
- * Built: 2026-05-30T10:04:07.992Z
4836
- * Commit: 0c4c061
4835
+ * Built: 2026-06-13T07:03:29.627Z
4836
+ * Commit: 8b31341
4837
4837
  */
4838
4838
 
4839
4839
  /**
@@ -5454,11 +5454,11 @@ body.dm-cloaked.dm-ready {
5454
5454
  ============================================ */
5455
5455
 
5456
5456
  /*!
5457
- * Domma Elements CSS v0.27.1
5457
+ * Domma Elements CSS v0.27.3
5458
5458
  * Dynamic Object Manipulation & Modeling API
5459
5459
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5460
- * Built: 2026-05-30T10:04:07.998Z
5461
- * Commit: 0c4c061
5460
+ * Built: 2026-06-13T07:03:29.632Z
5461
+ * Commit: 8b31341
5462
5462
  */
5463
5463
 
5464
5464
  /**
@@ -7918,7 +7918,7 @@ code {
7918
7918
  transition: transform 0.2s ease;
7919
7919
  }
7920
7920
 
7921
- .navbar-dropdown.open .navbar-caret {
7921
+ .navbar-dropdown.open > .navbar-dropdown-toggle:not(.navbar-submenu-toggle) .navbar-caret {
7922
7922
  transform: rotate(180deg);
7923
7923
  }
7924
7924
 
@@ -7938,7 +7938,7 @@ code {
7938
7938
  z-index: var(--dm-z-dropdown, 1000);
7939
7939
  }
7940
7940
 
7941
- .navbar-dropdown.open .navbar-dropdown-menu {
7941
+ .navbar-dropdown.open > .navbar-dropdown-menu {
7942
7942
  display: block;
7943
7943
  }
7944
7944
 
@@ -7995,6 +7995,89 @@ code {
7995
7995
  background: var(--dm-surface);
7996
7996
  }
7997
7997
 
7998
+ /* ============================================
7999
+ NAVBAR - NESTED (MULTI-LEVEL) DROPDOWNS
8000
+ ============================================ */
8001
+
8002
+ .navbar-dropdown-sub {
8003
+ position: relative;
8004
+ }
8005
+
8006
+ /* A submenu toggle looks like a dropdown item but opens a nested menu */
8007
+ .navbar-submenu-toggle {
8008
+ display: flex;
8009
+ align-items: center;
8010
+ justify-content: space-between;
8011
+ gap: 0.5rem;
8012
+ width: 100%;
8013
+ padding: 0.5rem 1rem;
8014
+ background: none;
8015
+ border: none;
8016
+ cursor: pointer;
8017
+ font: inherit;
8018
+ font-size: var(--dm-font-size-sm);
8019
+ color: var(--dm-text, #212529);
8020
+ text-align: left;
8021
+ text-decoration: none;
8022
+ }
8023
+
8024
+ .navbar-submenu-toggle:hover {
8025
+ background: var(--dm-hover-bg, rgba(0, 0, 0, 0.05));
8026
+ }
8027
+
8028
+ .navbar-light .navbar-submenu-toggle:hover,
8029
+ [data-mode="light"] .navbar-submenu-toggle:hover {
8030
+ background: #1e293b !important;
8031
+ color: #ffffff !important;
8032
+ border-radius: var(--dm-radius-md);
8033
+ }
8034
+
8035
+ .navbar-dark .navbar-submenu-toggle {
8036
+ color: var(--dm-gray-400, #adb5bd);
8037
+ }
8038
+
8039
+ .navbar-dark .navbar-submenu-toggle:hover {
8040
+ background: rgba(255, 255, 255, 0.3);
8041
+ color: var(--dm-text-inverse, var(--dm-white));
8042
+ }
8043
+
8044
+ /* Submenu caret points to the side to signal a fly-out */
8045
+ .navbar-submenu-toggle .navbar-caret {
8046
+ transform: rotate(-90deg);
8047
+ margin-left: auto;
8048
+ }
8049
+
8050
+ /* The nested menu flies out to the right of its parent entry (desktop) */
8051
+ .navbar-dropdown-submenu {
8052
+ top: 0;
8053
+ left: 100%;
8054
+ margin: 0 0 0 0.25rem;
8055
+ }
8056
+
8057
+ .navbar-dark .navbar-dropdown-submenu {
8058
+ background: var(--dm-surface);
8059
+ border-color: var(--dm-border-dark, var(--dm-border));
8060
+ }
8061
+
8062
+ /* On mobile the nested menu stacks and indents instead of flying out */
8063
+ @media (max-width: 992px) {
8064
+ .navbar-dropdown-submenu {
8065
+ position: static;
8066
+ left: auto;
8067
+ margin: 0;
8068
+ min-width: 0;
8069
+ padding: 0 0 0 0.75rem;
8070
+ border: none;
8071
+ border-left: 1px solid var(--dm-border, #dee2e6);
8072
+ border-radius: 0;
8073
+ box-shadow: none;
8074
+ }
8075
+
8076
+ .navbar-submenu-toggle .navbar-caret {
8077
+ transform: rotate(0deg);
8078
+ }
8079
+ }
8080
+
7998
8081
  /* Pill button styles (for Download button) */
7999
8082
  .pill {
8000
8083
  display: inline-block;
@@ -13317,11 +13400,11 @@ code {
13317
13400
  ============================================ */
13318
13401
 
13319
13402
  /*!
13320
- * Domma Themes v0.27.1
13403
+ * Domma Themes v0.27.3
13321
13404
  * Dynamic Object Manipulation & Modeling API
13322
13405
  * (c) 2026 Darryl Waterhouse & DCBW-IT
13323
- * Built: 2026-05-30T10:04:07.972Z
13324
- * Commit: 0c4c061
13406
+ * Built: 2026-06-13T07:03:29.606Z
13407
+ * Commit: 8b31341
13325
13408
  */
13326
13409
 
13327
13410
  /**