ngx-xtroedge-cms 1.1.0 → 1.2.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/dist/index.js CHANGED
@@ -32,32 +32,32 @@ var CMS_STYLES = `
32
32
  .lcms-loader-overlay {
33
33
  position: fixed; inset: 0; z-index: 10003;
34
34
  display: flex; align-items: center; justify-content: center;
35
- background: rgba(5, 20, 10, 0.45);
35
+ background: rgba(8, 8, 15, 0.45);
36
36
  backdrop-filter: blur(12px) saturate(1.4);
37
37
  -webkit-backdrop-filter: blur(12px) saturate(1.4);
38
38
  }
39
39
  .lcms-loader-content { display: flex; flex-direction: column; align-items: center; gap: 28px; }
40
40
  .lcms-orbit-loader { position: relative; width: 90px; height: 90px; }
41
41
  .lcms-orbit { position: absolute; inset: 0; border-radius: 50%; border: 1px solid transparent; }
42
- .lcms-orbit-1 { border-top-color: rgba(0,200,83,0.5); animation: lcmsSpin 2.4s linear infinite; }
43
- .lcms-orbit-2 { inset: 10px; border-right-color: rgba(76,175,80,0.5); animation: lcmsSpin 3.2s linear infinite reverse; }
44
- .lcms-orbit-3 { inset: 20px; border-bottom-color: rgba(129,199,132,0.5); animation: lcmsSpin 4.2s linear infinite; }
42
+ .lcms-orbit-1 { border-top-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.5); animation: lcmsSpin 2.4s linear infinite; }
43
+ .lcms-orbit-2 { inset: 10px; border-right-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.4); animation: lcmsSpin 3.2s linear infinite reverse; }
44
+ .lcms-orbit-3 { inset: 20px; border-bottom-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.35); animation: lcmsSpin 4.2s linear infinite; }
45
45
  .lcms-particle {
46
46
  position: absolute; width: 8px; height: 8px; border-radius: 50%; top: -4px; left: 50%; margin-left: -4px;
47
47
  box-shadow: 0 0 12px 3px currentColor;
48
48
  }
49
- .lcms-orbit-1 .lcms-particle { background: #00C853; color: #00C853; }
50
- .lcms-orbit-2 .lcms-particle { background: #4CAF50; color: #4CAF50; top: 50%; left: auto; right: -4px; margin-left: 0; margin-top: -4px; }
51
- .lcms-orbit-3 .lcms-particle { background: #81C784; color: #81C784; top: auto; bottom: -4px; }
49
+ .lcms-orbit-1 .lcms-particle { background: var(--lcms-primary, #00C853); color: var(--lcms-primary, #00C853); }
50
+ .lcms-orbit-2 .lcms-particle { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.8); color: rgba(var(--lcms-primary-rgb, 0,200,83),0.8); top: 50%; left: auto; right: -4px; margin-left: 0; margin-top: -4px; }
51
+ .lcms-orbit-3 .lcms-particle { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.6); color: rgba(var(--lcms-primary-rgb, 0,200,83),0.6); top: auto; bottom: -4px; }
52
52
  .lcms-core-glow {
53
53
  position: absolute; width: 30px; height: 30px; top: 50%; left: 50%; transform: translate(-50%,-50%);
54
- border-radius: 50%; background: radial-gradient(circle, rgba(0,200,83,0.4), transparent 70%);
54
+ border-radius: 50%; background: radial-gradient(circle, rgba(var(--lcms-primary-rgb, 0,200,83),0.4), transparent 70%);
55
55
  animation: lcmsPulse 2s ease-in-out infinite;
56
56
  }
57
57
  .lcms-core {
58
58
  position: absolute; width: 12px; height: 12px; top: 50%; left: 50%; transform: translate(-50%,-50%);
59
- border-radius: 50%; background: linear-gradient(135deg, #00C853, #81C784);
60
- box-shadow: 0 0 20px rgba(0,200,83,0.6);
59
+ border-radius: 50%; background: linear-gradient(135deg, var(--lcms-primary, #00C853), rgba(var(--lcms-primary-rgb, 0,200,83),0.6));
60
+ box-shadow: 0 0 20px rgba(var(--lcms-primary-rgb, 0,200,83),0.6);
61
61
  }
62
62
  .lcms-loader-text {
63
63
  font-family: system-ui, -apple-system, sans-serif; font-size: 12px; font-weight: 600;
@@ -74,10 +74,10 @@ var CMS_STYLES = `
74
74
  padding: 10px 20px; border-radius: 10px; font-size: 13px; font-weight: 600;
75
75
  font-family: system-ui, -apple-system, sans-serif; color: white;
76
76
  display: flex; align-items: center; gap: 8px;
77
- box-shadow: 0 8px 32px rgba(0,200,83,0.25);
77
+ box-shadow: 0 8px 32px rgba(var(--lcms-primary-rgb, 0,200,83),0.25);
78
78
  animation: lcmsToastIn 0.3s ease, lcmsToastOut 0.3s ease 2.7s forwards; white-space: nowrap;
79
79
  }
80
- .lcms-toast-success { background: linear-gradient(135deg, #00C853, #2E7D32); }
80
+ .lcms-toast-success { background: linear-gradient(135deg, var(--lcms-primary, #00C853), var(--lcms-primary-dark, #2E7D32)); }
81
81
  .lcms-toast-error { background: linear-gradient(135deg, #dc2626, #ef4444); }
82
82
  @keyframes lcmsToastIn { from { opacity: 0; transform: translateX(-50%) translateY(-12px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }
83
83
  @keyframes lcmsToastOut { from { opacity: 1; transform: translateX(-50%) translateY(0); } to { opacity: 0; transform: translateX(-50%) translateY(-12px); } }
@@ -86,15 +86,15 @@ var CMS_STYLES = `
86
86
  .lcms-fab { position: fixed; z-index: 10001; user-select: none; touch-action: none; }
87
87
  .lcms-fab-btn {
88
88
  width: 52px; height: 52px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.2);
89
- background: rgba(0,200,83,0.35); color: white;
89
+ background: rgba(var(--lcms-primary-rgb, 0,200,83),0.35); color: white;
90
90
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
91
91
  cursor: grab; display: flex; align-items: center; justify-content: center;
92
- box-shadow: 0 4px 20px rgba(0,200,83,0.3), inset 0 1px 0 rgba(255,255,255,0.15);
92
+ box-shadow: 0 4px 20px rgba(var(--lcms-primary-rgb, 0,200,83),0.3), inset 0 1px 0 rgba(255,255,255,0.15);
93
93
  transition: transform 0.2s, box-shadow 0.2s, background 0.2s; position: relative;
94
94
  }
95
- .lcms-fab-btn:not(.lcms-fab-active) { background: rgba(0,200,83,0.25); box-shadow: 0 4px 16px rgba(0,0,0,0.2), inset 0 1px 0 rgba(255,255,255,0.1); }
96
- .lcms-fab-btn.lcms-fab-active { background: rgba(0,200,83,0.4); box-shadow: 0 4px 24px rgba(0,200,83,0.4), 0 0 16px rgba(0,200,83,0.2), inset 0 1px 0 rgba(255,255,255,0.2); }
97
- .lcms-fab-btn:hover { transform: scale(1.08); background: rgba(0,200,83,0.5); box-shadow: 0 6px 28px rgba(0,200,83,0.4), inset 0 1px 0 rgba(255,255,255,0.2); }
95
+ .lcms-fab-btn:not(.lcms-fab-active) { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.25); box-shadow: 0 4px 16px rgba(0,0,0,0.2), inset 0 1px 0 rgba(255,255,255,0.1); }
96
+ .lcms-fab-btn.lcms-fab-active { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.4); box-shadow: 0 4px 24px rgba(var(--lcms-primary-rgb, 0,200,83),0.4), 0 0 16px rgba(var(--lcms-primary-rgb, 0,200,83),0.2), inset 0 1px 0 rgba(255,255,255,0.2); }
97
+ .lcms-fab-btn:hover { transform: scale(1.08); background: rgba(var(--lcms-primary-rgb, 0,200,83),0.5); box-shadow: 0 6px 28px rgba(var(--lcms-primary-rgb, 0,200,83),0.4), inset 0 1px 0 rgba(255,255,255,0.2); }
98
98
  .lcms-badge {
99
99
  position: absolute; top: -4px; right: -4px; background: #ef4444; color: white;
100
100
  font-size: 11px; font-weight: 700; width: 20px; height: 20px; border-radius: 50%;
@@ -103,27 +103,44 @@ var CMS_STYLES = `
103
103
 
104
104
  /* PANEL */
105
105
  .lcms-panel {
106
- background: rgba(10,30,15,0.55); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
107
- border: 1px solid rgba(76,175,80,0.25); border-radius: 16px; padding: 16px; min-width: 230px;
106
+ background: rgba(12,12,18,0.55); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
107
+ border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.25); border-radius: 16px; padding: 16px; min-width: 230px;
108
108
  box-shadow: 0 8px 32px rgba(0,0,0,0.25), inset 0 1px 0 rgba(255,255,255,0.06);
109
109
  color: white; font-family: system-ui, -apple-system, sans-serif;
110
110
  animation: lcmsPanelIn 0.25s ease; position: absolute;
111
111
  }
112
112
  @keyframes lcmsPanelIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } }
113
113
 
114
+ /* SITE IDENTIFIER */
115
+ .lcms-site-id {
116
+ display: flex; align-items: center; gap: 5px;
117
+ font-size: 10px; color: rgba(255,255,255,0.4);
118
+ padding: 0 0 8px; margin-bottom: 8px;
119
+ border-bottom: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.12);
120
+ font-family: system-ui, -apple-system, sans-serif;
121
+ letter-spacing: 0.3px;
122
+ }
123
+ .lcms-site-id-icon { font-size: 12px; opacity: 0.7; }
124
+ .lcms-site-id-text {
125
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 180px;
126
+ font-weight: 500;
127
+ }
128
+
114
129
  /* BRANDING */
115
130
  .lcms-branding {
116
131
  display: flex; align-items: center; gap: 6px; padding: 8px 0 4px;
117
- border-top: 1px solid rgba(76,175,80,0.15); margin-top: 10px;
132
+ border-top: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.15); margin-top: 10px;
133
+ cursor: pointer; transition: opacity 0.2s; user-select: none;
118
134
  }
135
+ .lcms-branding:hover { opacity: 0.8; }
119
136
  .lcms-branding-logo {
120
- width: 18px; height: 18px; border-radius: 4px; background: linear-gradient(135deg, #00C853, #2E7D32);
137
+ width: 18px; height: 18px; border-radius: 4px; background: linear-gradient(135deg, var(--lcms-primary, #00C853), var(--lcms-primary-dark, #2E7D32));
121
138
  display: flex; align-items: center; justify-content: center;
122
139
  }
123
140
  .lcms-branding-text {
124
141
  font-size: 10px; font-weight: 600; color: rgba(255,255,255,0.35); letter-spacing: 0.5px;
125
142
  }
126
- .lcms-branding-text span { color: #00C853; font-weight: 700; }
143
+ .lcms-branding-text span { color: var(--lcms-primary, #00C853); font-weight: 700; }
127
144
 
128
145
  .lcms-panel-header { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
129
146
  .lcms-toggle { display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; }
@@ -136,53 +153,84 @@ var CMS_STYLES = `
136
153
  content: ''; position: absolute; width: 16px; height: 16px; border-radius: 50%;
137
154
  top: 2px; left: 2px; background: rgba(255,255,255,0.6); transition: transform 0.25s, background 0.25s;
138
155
  }
139
- .lcms-toggle input:checked + .lcms-toggle-slider { background: #00C853; }
156
+ .lcms-toggle input:checked + .lcms-toggle-slider { background: var(--lcms-primary, #00C853); }
140
157
  .lcms-toggle input:checked + .lcms-toggle-slider::after { transform: translateX(16px); background: white; }
141
158
  .lcms-toggle-label { font-size: 12px; font-weight: 700; color: rgba(255,255,255,0.5); letter-spacing: 0.5px; transition: color 0.25s; }
142
- .lcms-toggle input:checked ~ .lcms-toggle-label { color: #81C784; }
143
- .lcms-lang-switch { display: flex; border: 1px solid rgba(0,200,83,0.4); border-radius: 6px; overflow: hidden; margin-left: auto; }
159
+ .lcms-toggle input:checked ~ .lcms-toggle-label { color: rgba(var(--lcms-primary-rgb, 0,200,83),0.75); }
160
+ .lcms-lang-switch { display: flex; border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.4); border-radius: 6px; overflow: hidden; margin-left: auto; }
144
161
  .lcms-lang-btn { background: transparent; border: none; color: rgba(255,255,255,0.45); padding: 3px 12px; font-size: 11px; font-weight: 600; cursor: pointer; transition: all 0.2s; }
145
- .lcms-lang-btn.active { background: #00C853; color: white; }
146
- .lcms-lang-btn:hover:not(.active) { color: white; background: rgba(0,200,83,0.2); }
162
+ .lcms-lang-btn.active { background: var(--lcms-primary, #00C853); color: white; }
163
+ .lcms-lang-btn:hover:not(.active) { color: white; background: rgba(var(--lcms-primary-rgb, 0,200,83),0.2); }
147
164
  .lcms-close-btn { background: transparent; border: none; color: rgba(255,255,255,0.4); cursor: pointer; padding: 2px; display: flex; transition: color 0.2s; }
148
165
  .lcms-close-btn:hover { color: white; }
149
- .lcms-changes-info { font-size: 12px; color: #81C784; margin-bottom: 10px; padding-left: 2px; }
166
+ .lcms-changes-info { font-size: 12px; color: rgba(var(--lcms-primary-rgb, 0,200,83),0.75); margin-bottom: 10px; padding-left: 2px; }
150
167
 
151
168
  .lcms-undo-row { display: flex; gap: 6px; margin-bottom: 12px; }
152
169
  .lcms-icon-btn {
153
- width: 36px; height: 32px; border-radius: 8px; border: 1px solid rgba(0,200,83,0.3);
154
- background: rgba(0,200,83,0.1); color: rgba(255,255,255,0.8); cursor: pointer;
170
+ width: 36px; height: 32px; border-radius: 8px; border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.3);
171
+ background: rgba(var(--lcms-primary-rgb, 0,200,83),0.1); color: rgba(255,255,255,0.8); cursor: pointer;
155
172
  display: flex; align-items: center; justify-content: center; transition: all 0.2s;
156
173
  }
157
- .lcms-icon-btn:hover:not(:disabled) { background: rgba(0,200,83,0.25); border-color: rgba(0,200,83,0.5); color: white; }
174
+ .lcms-icon-btn:hover:not(:disabled) { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.25); border-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.5); color: white; }
158
175
  .lcms-icon-btn:disabled { opacity: 0.25; cursor: not-allowed; }
159
176
 
177
+ /* COLOR THEME PICKER */
178
+ .lcms-theme-row {
179
+ display: flex; align-items: center; gap: 8px; margin-bottom: 12px;
180
+ padding: 6px 0;
181
+ }
182
+ .lcms-theme-label {
183
+ font-size: 10px; font-weight: 700; color: rgba(255,255,255,0.45);
184
+ text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap;
185
+ }
186
+ .lcms-theme-colors {
187
+ display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
188
+ }
189
+ .lcms-theme-swatch {
190
+ width: 20px; height: 20px; border-radius: 50%; border: 2px solid transparent;
191
+ cursor: pointer; transition: all 0.2s; position: relative;
192
+ }
193
+ .lcms-theme-swatch:hover { transform: scale(1.15); }
194
+ .lcms-theme-swatch.active { border-color: white; box-shadow: 0 0 8px rgba(255,255,255,0.3); }
195
+ .lcms-theme-custom {
196
+ width: 20px; height: 20px; border-radius: 50%; border: 1px dashed rgba(255,255,255,0.3);
197
+ cursor: pointer; overflow: hidden; position: relative;
198
+ }
199
+ .lcms-theme-custom input {
200
+ position: absolute; inset: -4px; width: 28px; height: 28px; border: none;
201
+ background: transparent; cursor: pointer; opacity: 0;
202
+ }
203
+ .lcms-theme-custom-preview {
204
+ width: 100%; height: 100%; border-radius: 50%;
205
+ background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
206
+ }
207
+
160
208
  .lcms-history-btn {
161
209
  width: 100%; padding: 7px 12px; border-radius: 8px;
162
- border: 1px dashed rgba(76,175,80,0.35); background: rgba(0,200,83,0.08);
210
+ border: 1px dashed rgba(var(--lcms-primary-rgb, 0,200,83),0.35); background: rgba(var(--lcms-primary-rgb, 0,200,83),0.08);
163
211
  color: rgba(255,255,255,0.6); font-size: 12px; font-weight: 500; cursor: pointer;
164
212
  display: flex; align-items: center; justify-content: center; gap: 6px;
165
213
  transition: all 0.2s; margin-bottom: 12px; font-family: system-ui, -apple-system, sans-serif;
166
214
  }
167
- .lcms-history-btn:hover { background: rgba(0,200,83,0.18); border-color: rgba(76,175,80,0.5); color: white; }
168
- .lcms-history-btn.active { background: rgba(0,200,83,0.25); border-color: #00C853; border-style: solid; color: white; }
215
+ .lcms-history-btn:hover { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.18); border-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.5); color: white; }
216
+ .lcms-history-btn.active { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.25); border-color: var(--lcms-primary, #00C853); border-style: solid; color: white; }
169
217
 
170
- .lcms-history-panel { margin-top: 8px; border-top: 1px solid rgba(76,175,80,0.15); padding-top: 10px; }
218
+ .lcms-history-panel { margin-top: 8px; border-top: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.15); padding-top: 10px; }
171
219
  .lcms-history-title { font-size: 11px; font-weight: 700; color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }
172
220
  .lcms-history-empty { font-size: 12px; color: rgba(255,255,255,0.3); text-align: center; padding: 12px 0; }
173
221
  .lcms-history-list { max-height: 200px; overflow-y: auto; display: flex; flex-direction: column; gap: 4px; }
174
222
  .lcms-history-list::-webkit-scrollbar { width: 4px; }
175
223
  .lcms-history-list::-webkit-scrollbar-track { background: transparent; }
176
- .lcms-history-list::-webkit-scrollbar-thumb { background: rgba(0,200,83,0.3); border-radius: 4px; }
224
+ .lcms-history-list::-webkit-scrollbar-thumb { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.3); border-radius: 4px; }
177
225
  .lcms-history-item {
178
- width: 100%; text-align: left; background: rgba(0,200,83,0.06);
179
- border: 1px solid rgba(0,200,83,0.12); border-radius: 8px; padding: 8px 10px;
226
+ width: 100%; text-align: left; background: rgba(var(--lcms-primary-rgb, 0,200,83),0.06);
227
+ border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.12); border-radius: 8px; padding: 8px 10px;
180
228
  cursor: pointer; transition: all 0.2s; color: white; font-family: system-ui, -apple-system, sans-serif;
181
229
  }
182
- .lcms-history-item:hover { background: rgba(0,200,83,0.15); border-color: rgba(0,200,83,0.3); }
230
+ .lcms-history-item:hover { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.15); border-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.3); }
183
231
  .lcms-history-label { font-size: 12px; font-weight: 500; margin-bottom: 2px; }
184
232
  .lcms-history-meta { font-size: 10px; color: rgba(255,255,255,0.4); display: flex; align-items: center; gap: 6px; }
185
- .lcms-history-lang { background: rgba(0,200,83,0.2); padding: 1px 5px; border-radius: 3px; font-size: 9px; font-weight: 600; color: #81C784; }
233
+ .lcms-history-lang { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.2); padding: 1px 5px; border-radius: 3px; font-size: 9px; font-weight: 600; color: rgba(var(--lcms-primary-rgb, 0,200,83),0.75); }
186
234
 
187
235
  .lcms-actions { display: flex; flex-direction: column; gap: 6px; }
188
236
  .lcms-actions button {
@@ -190,14 +238,14 @@ var CMS_STYLES = `
190
238
  cursor: pointer; transition: all 0.2s; display: flex; align-items: center; justify-content: center; gap: 6px; border: none;
191
239
  font-family: system-ui, -apple-system, sans-serif;
192
240
  }
193
- .lcms-btn-save { background: #00C853; color: white; }
194
- .lcms-btn-save:hover { background: #00E676; }
195
- .lcms-btn-save:disabled { background: rgba(0,200,83,0.2); color: rgba(255,255,255,0.35); cursor: not-allowed; }
241
+ .lcms-btn-save { background: var(--lcms-primary, #00C853); color: white; }
242
+ .lcms-btn-save:hover { background: var(--lcms-primary, #00C853); filter: brightness(1.15); }
243
+ .lcms-btn-save:disabled { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.2); color: rgba(255,255,255,0.35); cursor: not-allowed; filter: none; }
196
244
  .lcms-btn-publish { background: linear-gradient(135deg, #2196F3, #1976D2); color: white; }
197
245
  .lcms-btn-publish:hover { background: linear-gradient(135deg, #1976D2, #1565C0); }
198
- .lcms-btn-publish:disabled { background: rgba(0,200,83,0.2); color: rgba(255,255,255,0.35); cursor: not-allowed; }
199
- .lcms-btn-cancel { background: transparent; color: rgba(255,255,255,0.5); border: 1px solid rgba(0,200,83,0.25) !important; }
200
- .lcms-btn-cancel:hover { color: white; border-color: rgba(0,200,83,0.5) !important; background: rgba(0,200,83,0.08); }
246
+ .lcms-btn-publish:disabled { background: rgba(var(--lcms-primary-rgb, 0,200,83),0.2); color: rgba(255,255,255,0.35); cursor: not-allowed; }
247
+ .lcms-btn-cancel { background: transparent; color: rgba(255,255,255,0.5); border: 1px solid rgba(var(--lcms-primary-rgb, 0,200,83),0.25) !important; }
248
+ .lcms-btn-cancel:hover { color: white; border-color: rgba(var(--lcms-primary-rgb, 0,200,83),0.5) !important; background: rgba(var(--lcms-primary-rgb, 0,200,83),0.08); }
201
249
  .lcms-btn-cancel:disabled { opacity: 0.3; cursor: not-allowed; }
202
250
 
203
251
  .lcms-spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.3); border-top-color: white; border-radius: 50%; animation: lcmsSpin 0.6s linear infinite; }
@@ -206,14 +254,14 @@ var CMS_STYLES = `
206
254
  .lcms-img-upload-overlay {
207
255
  position: fixed; inset: 0; z-index: 10005;
208
256
  display: flex; align-items: center; justify-content: center;
209
- background: rgba(5, 20, 10, 0.5); backdrop-filter: blur(8px);
257
+ background: rgba(8, 8, 15, 0.5); backdrop-filter: blur(8px);
210
258
  }
211
259
  .lcms-img-upload-content {
212
260
  display: flex; flex-direction: column; align-items: center; gap: 16px;
213
261
  color: white; font-family: system-ui, -apple-system, sans-serif;
214
262
  font-size: 13px; font-weight: 600;
215
263
  }
216
- .lcms-spinner-lg { width: 36px; height: 36px; border: 3px solid rgba(255,255,255,0.2); border-top-color: #00C853; border-radius: 50%; animation: lcmsSpin 0.6s linear infinite; }
264
+ .lcms-spinner-lg { width: 36px; height: 36px; border: 3px solid rgba(255,255,255,0.2); border-top-color: var(--lcms-primary, #00C853); border-radius: 50%; animation: lcmsSpin 0.6s linear infinite; }
217
265
 
218
266
  /* HIDDEN ELEMENTS */
219
267
  .lcms-hidden { display: none !important; }
@@ -259,6 +307,8 @@ var DEFAULT_EDITABLE_TAGS = [
259
307
  var XtroedgeCMS = class _XtroedgeCMS {
260
308
  constructor(config) {
261
309
  this.brandingEl = null;
310
+ this.siteIdentifier = "";
311
+ this.siteIdEl = null;
262
312
  // ===== State =====
263
313
  this.editMode = false;
264
314
  this.currentLang = "en";
@@ -345,6 +395,9 @@ var XtroedgeCMS = class _XtroedgeCMS {
345
395
  this.highlightColor = this.config.highlightColor || "#00C853";
346
396
  this.historyRetentionMs = (this.config.historyRetentionDays || 7) * 24 * 60 * 60 * 1e3;
347
397
  this.currentLang = this.defaultLanguage;
398
+ this.siteIdentifier = this.resolveSiteIdentifier();
399
+ const savedColor = localStorage.getItem("xtroedge_theme_color");
400
+ if (savedColor) this.highlightColor = savedColor;
348
401
  this.boundMouseMove = (e) => this.onDragMove(e);
349
402
  this.boundMouseUp = () => this.onDragEnd();
350
403
  this.boundTouchMove = (e) => this.onTouchMove(e);
@@ -358,6 +411,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
358
411
  init() {
359
412
  this.posY = window.innerHeight - 72;
360
413
  this.injectStyles();
414
+ this.applyThemeColor(this.highlightColor);
361
415
  this.buildUI();
362
416
  this.interceptNavigation();
363
417
  this.observer = new MutationObserver(() => {
@@ -529,6 +583,10 @@ var XtroedgeCMS = class _XtroedgeCMS {
529
583
  });
530
584
  header.appendChild(closeBtn);
531
585
  this.panelEl.appendChild(header);
586
+ this.siteIdEl = this.createElement("div", "lcms-site-id");
587
+ const isDomain = this.siteIdentifier.includes(".");
588
+ this.siteIdEl.innerHTML = `<span class="lcms-site-id-icon">${isDomain ? "\u{1F310}" : "\u{1F511}"}</span><span class="lcms-site-id-text">${isDomain ? this.siteIdentifier : this.siteIdentifier.substring(0, 8)}</span>`;
589
+ this.panelEl.appendChild(this.siteIdEl);
532
590
  this.editModeContent = this.createElement("div", "lcms-hidden");
533
591
  this.changesInfoEl = this.createElement("div", "lcms-changes-info lcms-hidden");
534
592
  this.editModeContent.appendChild(this.changesInfoEl);
@@ -552,6 +610,37 @@ var XtroedgeCMS = class _XtroedgeCMS {
552
610
  undoRow.appendChild(this.undoBtn);
553
611
  undoRow.appendChild(this.redoBtn);
554
612
  this.editModeContent.appendChild(undoRow);
613
+ const themeRow = this.createElement("div", "lcms-theme-row");
614
+ const themeLabel = this.createElement("span", "lcms-theme-label");
615
+ themeLabel.textContent = "Theme";
616
+ themeRow.appendChild(themeLabel);
617
+ const themeColors = this.createElement("div", "lcms-theme-colors");
618
+ const presetColors = ["#00C853", "#6722FB", "#2196F3", "#FF5722", "#E91E63", "#FFD600"];
619
+ for (const color of presetColors) {
620
+ const swatch = this.createElement("div", "lcms-theme-swatch");
621
+ swatch.style.background = color;
622
+ swatch.dataset.color = color;
623
+ if (color === this.highlightColor) swatch.classList.add("active");
624
+ swatch.addEventListener("click", (e) => {
625
+ e.stopPropagation();
626
+ this.applyThemeColor(color);
627
+ });
628
+ themeColors.appendChild(swatch);
629
+ }
630
+ const customSwatch = this.createElement("div", "lcms-theme-custom");
631
+ const customPreview = this.createElement("div", "lcms-theme-custom-preview");
632
+ const customInput = document.createElement("input");
633
+ customInput.type = "color";
634
+ customInput.value = this.highlightColor;
635
+ customInput.addEventListener("input", (e) => {
636
+ e.stopPropagation();
637
+ this.applyThemeColor(e.target.value);
638
+ });
639
+ customSwatch.appendChild(customPreview);
640
+ customSwatch.appendChild(customInput);
641
+ themeColors.appendChild(customSwatch);
642
+ themeRow.appendChild(themeColors);
643
+ this.editModeContent.appendChild(themeRow);
555
644
  this.historyBtnEl = document.createElement("button");
556
645
  this.historyBtnEl.className = "lcms-history-btn";
557
646
  this.historyBtnEl.innerHTML = `${ICON.history} History (7 days)`;
@@ -596,6 +685,10 @@ var XtroedgeCMS = class _XtroedgeCMS {
596
685
  this.panelEl.appendChild(this.editModeContent);
597
686
  this.brandingEl = this.createElement("div", "lcms-branding");
598
687
  this.brandingEl.innerHTML = `<div class="lcms-branding-logo"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg></div><div class="lcms-branding-text">Powered by <span>XtroEdge</span></div>`;
688
+ this.brandingEl.addEventListener("click", (e) => {
689
+ e.stopPropagation();
690
+ window.open("https://xtro.vercel.app/", "_blank");
691
+ });
599
692
  this.panelEl.appendChild(this.brandingEl);
600
693
  }
601
694
  buildLangButtons() {
@@ -1148,7 +1241,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
1148
1241
  this.setLoading(true);
1149
1242
  this.cleanOldHistory();
1150
1243
  try {
1151
- const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=${status}`);
1244
+ const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=${status}&site_identifier=${encodeURIComponent(this.siteIdentifier)}`);
1152
1245
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
1153
1246
  const page = await res.json();
1154
1247
  const texts = page?.published_content?.texts || page?.content?.texts;
@@ -1178,7 +1271,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
1178
1271
  async loadPublishedContent() {
1179
1272
  this.setLoading(true);
1180
1273
  try {
1181
- const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=published`);
1274
+ const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=published&site_identifier=${encodeURIComponent(this.siteIdentifier)}`);
1182
1275
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
1183
1276
  const page = await res.json();
1184
1277
  const texts = page?.published_content?.texts;
@@ -1237,6 +1330,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
1237
1330
  const payload = {
1238
1331
  slug: this.currentSlug,
1239
1332
  title: this.currentTitle,
1333
+ site_identifier: this.siteIdentifier,
1240
1334
  content: { texts: this.pageTexts, images: this.pageImages }
1241
1335
  };
1242
1336
  try {
@@ -1268,6 +1362,7 @@ var XtroedgeCMS = class _XtroedgeCMS {
1268
1362
  const payload = {
1269
1363
  slug: this.currentSlug,
1270
1364
  title: this.currentTitle,
1365
+ site_identifier: this.siteIdentifier,
1271
1366
  published_content: { texts: this.pageTexts, images: this.pageImages }
1272
1367
  };
1273
1368
  try {
@@ -1544,6 +1639,59 @@ var XtroedgeCMS = class _XtroedgeCMS {
1544
1639
  return `${months[d.getMonth()]} ${d.getDate()}, ${h12}:${m} ${ampm}`;
1545
1640
  }
1546
1641
  // ===============================================
1642
+ // SITE IDENTIFIER
1643
+ // ===============================================
1644
+ resolveSiteIdentifier() {
1645
+ const hostname = window.location.hostname;
1646
+ if (hostname && hostname !== "localhost" && hostname !== "127.0.0.1" && !hostname.startsWith("192.168.")) {
1647
+ return hostname;
1648
+ }
1649
+ let id = localStorage.getItem("xtroedge_site_id");
1650
+ if (!id) {
1651
+ id = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
1652
+ const r = Math.random() * 16 | 0;
1653
+ return (c === "x" ? r : r & 3 | 8).toString(16);
1654
+ });
1655
+ localStorage.setItem("xtroedge_site_id", id);
1656
+ }
1657
+ return id;
1658
+ }
1659
+ // ===============================================
1660
+ // THEME COLOR
1661
+ // ===============================================
1662
+ hexToRgb(hex) {
1663
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
1664
+ if (!result) return "0,200,83";
1665
+ return `${parseInt(result[1], 16)},${parseInt(result[2], 16)},${parseInt(result[3], 16)}`;
1666
+ }
1667
+ getDarkerColor(hex) {
1668
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
1669
+ if (!result) return "#2E7D32";
1670
+ const r = Math.max(0, Math.floor(parseInt(result[1], 16) * 0.6));
1671
+ const g = Math.max(0, Math.floor(parseInt(result[2], 16) * 0.6));
1672
+ const b = Math.max(0, Math.floor(parseInt(result[3], 16) * 0.6));
1673
+ return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
1674
+ }
1675
+ applyThemeColor(color) {
1676
+ this.highlightColor = color;
1677
+ document.documentElement.style.setProperty("--lcms-primary", color);
1678
+ document.documentElement.style.setProperty("--lcms-primary-rgb", this.hexToRgb(color));
1679
+ document.documentElement.style.setProperty("--lcms-primary-dark", this.getDarkerColor(color));
1680
+ if (this.editMode) {
1681
+ for (const [el] of this.managedElements) {
1682
+ el.style.borderBottom = `2px dashed ${color}`;
1683
+ }
1684
+ for (const [img] of this.managedImages) {
1685
+ img.style.outline = `2px dashed ${color}`;
1686
+ }
1687
+ }
1688
+ const swatches = this.panelEl?.querySelectorAll(".lcms-theme-swatch");
1689
+ swatches?.forEach((s) => {
1690
+ s.classList.toggle("active", s.dataset.color === color);
1691
+ });
1692
+ localStorage.setItem("xtroedge_theme_color", color);
1693
+ }
1694
+ // ===============================================
1547
1695
  // STATIC CONVENIENCE
1548
1696
  // ===============================================
1549
1697
  /** Quick init - create and start CMS in one call */