vibespot 0.4.4 → 0.5.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/assets/conversion-guide.md +28 -0
- package/assets/design-guide.md +1 -0
- package/assets/hubspot-rules.md +16 -3
- package/assets/humanify-guide.md +459 -0
- package/dist/index.js +99 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/ui/chat.js +199 -55
- package/ui/dashboard.js +19 -0
- package/ui/field-editor.js +9 -7
- package/ui/index.html +58 -31
- package/ui/setup.js +117 -36
- package/ui/styles.css +678 -243
package/package.json
CHANGED
package/ui/chat.js
CHANGED
|
@@ -184,14 +184,14 @@ function appendUserMessage(text, timestamp) {
|
|
|
184
184
|
const div = document.createElement("div");
|
|
185
185
|
div.className = "chat-msg chat-msg--user";
|
|
186
186
|
div.innerHTML = `
|
|
187
|
+
<div class="chat-msg__avatar chat-msg__avatar--user">Y</div>
|
|
187
188
|
<div class="chat-msg__content">
|
|
188
189
|
<div class="chat-msg__header">
|
|
189
190
|
<span class="chat-msg__sender">You</span>
|
|
190
191
|
<span class="chat-msg__time">${time}</span>
|
|
191
192
|
</div>
|
|
192
193
|
<div class="chat-msg__bubble">${escapeHtml(text)}</div>
|
|
193
|
-
</div
|
|
194
|
-
<div class="chat-msg__avatar chat-msg__avatar--user">Y</div>`;
|
|
194
|
+
</div>`;
|
|
195
195
|
messagesEl.appendChild(div);
|
|
196
196
|
scrollToBottom();
|
|
197
197
|
}
|
|
@@ -525,9 +525,11 @@ function timeAgoShort(timestamp) {
|
|
|
525
525
|
|
|
526
526
|
function updateModuleList(moduleNames) {
|
|
527
527
|
const itemsEl = document.getElementById("module-items");
|
|
528
|
-
const
|
|
528
|
+
const barCountEl = document.getElementById("module-count");
|
|
529
|
+
const slideoutCountEl = document.getElementById("slideout-module-count");
|
|
529
530
|
|
|
530
|
-
|
|
531
|
+
if (barCountEl) barCountEl.textContent = moduleNames.length;
|
|
532
|
+
if (slideoutCountEl) slideoutCountEl.textContent = moduleNames.length;
|
|
531
533
|
itemsEl.innerHTML = "";
|
|
532
534
|
|
|
533
535
|
for (const name of moduleNames) {
|
|
@@ -541,20 +543,12 @@ function updateModuleList(moduleNames) {
|
|
|
541
543
|
<span class="module-item__delete" title="Delete module">×</span>
|
|
542
544
|
`;
|
|
543
545
|
|
|
544
|
-
// Click to scroll to module in preview
|
|
545
|
-
item.querySelector(".module-item__name").addEventListener("click", () => {
|
|
546
|
-
scrollPreviewToModule(name);
|
|
547
|
-
highlightModuleItem(name);
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
// Click gear to open field editor
|
|
551
546
|
item.querySelector(".module-item__edit").addEventListener("click", (e) => {
|
|
552
547
|
e.stopPropagation();
|
|
553
548
|
openFieldEditor(name);
|
|
554
549
|
highlightModuleItem(name);
|
|
555
550
|
});
|
|
556
551
|
|
|
557
|
-
// Click × to delete module
|
|
558
552
|
item.querySelector(".module-item__delete").addEventListener("click", (e) => {
|
|
559
553
|
e.stopPropagation();
|
|
560
554
|
confirmDeleteModule(name);
|
|
@@ -563,7 +557,6 @@ function updateModuleList(moduleNames) {
|
|
|
563
557
|
itemsEl.appendChild(item);
|
|
564
558
|
}
|
|
565
559
|
|
|
566
|
-
// Set up drag-and-drop reordering
|
|
567
560
|
setupDragReorder(itemsEl);
|
|
568
561
|
}
|
|
569
562
|
|
|
@@ -573,6 +566,32 @@ function highlightModuleItem(name) {
|
|
|
573
566
|
});
|
|
574
567
|
}
|
|
575
568
|
|
|
569
|
+
// ---------------------------------------------------------------------------
|
|
570
|
+
// Module slideout
|
|
571
|
+
// ---------------------------------------------------------------------------
|
|
572
|
+
|
|
573
|
+
function openModuleSlideout() {
|
|
574
|
+
const slideout = document.getElementById("module-slideout");
|
|
575
|
+
document.getElementById("module-list-view").classList.remove("hidden");
|
|
576
|
+
document.getElementById("module-editor-view").classList.add("hidden");
|
|
577
|
+
slideout.classList.add("open");
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
function closeModuleSlideout() {
|
|
581
|
+
document.getElementById("module-slideout").classList.remove("open");
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
function showEditorView(moduleName) {
|
|
585
|
+
document.getElementById("module-list-view").classList.add("hidden");
|
|
586
|
+
document.getElementById("module-editor-view").classList.remove("hidden");
|
|
587
|
+
document.getElementById("module-slideout").classList.add("open");
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
function showModuleListView() {
|
|
591
|
+
document.getElementById("module-editor-view").classList.add("hidden");
|
|
592
|
+
document.getElementById("module-list-view").classList.remove("hidden");
|
|
593
|
+
}
|
|
594
|
+
|
|
576
595
|
// ---------------------------------------------------------------------------
|
|
577
596
|
// Module library — add modules from other templates
|
|
578
597
|
// ---------------------------------------------------------------------------
|
|
@@ -646,9 +665,24 @@ async function addModuleFromLibrary(moduleName) {
|
|
|
646
665
|
}
|
|
647
666
|
}
|
|
648
667
|
|
|
649
|
-
//
|
|
668
|
+
// Module bar button → toggle slideout
|
|
669
|
+
document.getElementById("btn-modules")?.addEventListener("click", () => {
|
|
670
|
+
const slideout = document.getElementById("module-slideout");
|
|
671
|
+
if (slideout.classList.contains("open")) {
|
|
672
|
+
closeModuleSlideout();
|
|
673
|
+
} else {
|
|
674
|
+
openModuleSlideout();
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
// Add module button (inside slideout)
|
|
650
679
|
document.getElementById("btn-add-module").addEventListener("click", toggleModuleLibraryDropdown);
|
|
651
680
|
|
|
681
|
+
// Slideout close buttons
|
|
682
|
+
document.getElementById("module-slideout-close")?.addEventListener("click", closeModuleSlideout);
|
|
683
|
+
document.getElementById("field-editor-back")?.addEventListener("click", showModuleListView);
|
|
684
|
+
document.getElementById("field-editor-close")?.addEventListener("click", closeModuleSlideout);
|
|
685
|
+
|
|
652
686
|
// Close dropdown when clicking outside
|
|
653
687
|
document.addEventListener("click", (e) => {
|
|
654
688
|
const dropdown = document.getElementById("module-library-dropdown");
|
|
@@ -658,62 +692,172 @@ document.addEventListener("click", (e) => {
|
|
|
658
692
|
}
|
|
659
693
|
});
|
|
660
694
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
695
|
+
function confirmDeleteModule(moduleName) {
|
|
696
|
+
return new Promise((resolve) => {
|
|
697
|
+
let deleteEntirely = false;
|
|
698
|
+
|
|
699
|
+
const overlay = document.createElement("div");
|
|
700
|
+
overlay.className = "confirm-overlay";
|
|
701
|
+
overlay.innerHTML = `
|
|
702
|
+
<div class="confirm-dialog">
|
|
703
|
+
<div class="confirm-dialog__title">Remove "${escapeHtml(moduleName)}"?</div>
|
|
704
|
+
<p class="confirm-dialog__detail">Module will be removed from this page but kept in your library.</p>
|
|
705
|
+
<label class="confirm-dialog__toggle">
|
|
706
|
+
<span class="confirm-dialog__toggle-switch">
|
|
707
|
+
<input type="checkbox" data-role="toggle" />
|
|
708
|
+
<span class="confirm-dialog__toggle-slider"></span>
|
|
709
|
+
</span>
|
|
710
|
+
<span class="confirm-dialog__toggle-label">Delete entirely</span>
|
|
711
|
+
</label>
|
|
712
|
+
<div class="confirm-dialog__toggle-warn">Cannot be undone!</div>
|
|
713
|
+
<div class="confirm-dialog__actions">
|
|
714
|
+
<button class="btn btn--secondary" data-action="cancel">Cancel</button>
|
|
715
|
+
<button class="btn btn--primary" data-action="confirm">Remove</button>
|
|
716
|
+
</div>
|
|
717
|
+
</div>
|
|
718
|
+
`;
|
|
719
|
+
document.body.appendChild(overlay);
|
|
720
|
+
|
|
721
|
+
const toggle = overlay.querySelector('[data-role="toggle"]');
|
|
722
|
+
const confirmBtn = overlay.querySelector('[data-action="confirm"]');
|
|
723
|
+
const warnEl = overlay.querySelector(".confirm-dialog__toggle-warn");
|
|
724
|
+
warnEl.style.display = "none";
|
|
725
|
+
|
|
726
|
+
toggle.addEventListener("change", () => {
|
|
727
|
+
deleteEntirely = toggle.checked;
|
|
728
|
+
if (deleteEntirely) {
|
|
729
|
+
confirmBtn.textContent = "Delete";
|
|
730
|
+
confirmBtn.className = "btn btn--danger";
|
|
731
|
+
warnEl.style.display = "";
|
|
732
|
+
} else {
|
|
733
|
+
confirmBtn.textContent = "Remove";
|
|
734
|
+
confirmBtn.className = "btn btn--primary";
|
|
735
|
+
warnEl.style.display = "none";
|
|
736
|
+
}
|
|
670
737
|
});
|
|
671
|
-
|
|
672
|
-
const
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
738
|
+
|
|
739
|
+
const close = (confirmed) => {
|
|
740
|
+
overlay.remove();
|
|
741
|
+
if (!confirmed) { resolve(); return; }
|
|
742
|
+
|
|
743
|
+
fetch("/api/modules", {
|
|
744
|
+
method: "DELETE",
|
|
745
|
+
headers: { "Content-Type": "application/json" },
|
|
746
|
+
body: JSON.stringify({ moduleName, deleteEntirely }),
|
|
747
|
+
}).then(() => {
|
|
748
|
+
const item = document.querySelector(`.module-item[data-module="${CSS.escape(moduleName)}"]`);
|
|
749
|
+
if (item) item.remove();
|
|
750
|
+
const countEl = document.getElementById("module-count");
|
|
751
|
+
const slideoutCountEl = document.getElementById("slideout-module-count");
|
|
752
|
+
const count = document.querySelectorAll(".module-item").length;
|
|
753
|
+
if (countEl) countEl.textContent = count;
|
|
754
|
+
if (slideoutCountEl) slideoutCountEl.textContent = count;
|
|
755
|
+
refreshPreview();
|
|
756
|
+
resolve();
|
|
757
|
+
}).catch(() => resolve());
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
overlay.querySelector('[data-action="cancel"]').addEventListener("click", () => close(false));
|
|
761
|
+
confirmBtn.addEventListener("click", () => close(true));
|
|
762
|
+
overlay.addEventListener("click", (e) => { if (e.target === overlay) close(false); });
|
|
763
|
+
});
|
|
680
764
|
}
|
|
681
765
|
|
|
682
766
|
// ---------------------------------------------------------------------------
|
|
683
|
-
// Drag-and-drop reordering
|
|
767
|
+
// Drag-and-drop reordering (smooth sortable animation)
|
|
684
768
|
// ---------------------------------------------------------------------------
|
|
685
769
|
|
|
686
770
|
function setupDragReorder(container) {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
const
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
771
|
+
container.querySelectorAll(".module-item").forEach((item) => {
|
|
772
|
+
item.addEventListener("mousedown", (e) => {
|
|
773
|
+
// Skip if clicking on edit/delete controls
|
|
774
|
+
if (e.target.closest(".module-item__edit") || e.target.closest(".module-item__delete")) return;
|
|
775
|
+
|
|
776
|
+
e.preventDefault();
|
|
777
|
+
const dragItem = item;
|
|
778
|
+
const moduleName = dragItem.dataset.module;
|
|
779
|
+
const startY = e.clientY;
|
|
780
|
+
const DRAG_THRESHOLD = 5;
|
|
781
|
+
let isDragging = false;
|
|
782
|
+
let items, startIdx, itemRects, itemHeight, currentIdx;
|
|
783
|
+
|
|
784
|
+
const startDrag = () => {
|
|
785
|
+
isDragging = true;
|
|
786
|
+
items = [...container.querySelectorAll(".module-item")];
|
|
787
|
+
startIdx = items.indexOf(dragItem);
|
|
788
|
+
itemRects = items.map((it) => it.getBoundingClientRect());
|
|
789
|
+
itemHeight = itemRects[startIdx]?.height || 36;
|
|
790
|
+
currentIdx = startIdx;
|
|
791
|
+
|
|
792
|
+
dragItem.classList.add("module-item--dragging");
|
|
793
|
+
items.forEach((it) => {
|
|
794
|
+
if (it !== dragItem) it.classList.add("module-item--placeholder");
|
|
795
|
+
});
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
const onMove = (ev) => {
|
|
799
|
+
const dy = ev.clientY - startY;
|
|
800
|
+
|
|
801
|
+
if (!isDragging) {
|
|
802
|
+
if (Math.abs(dy) >= DRAG_THRESHOLD) {
|
|
803
|
+
startDrag();
|
|
804
|
+
} else {
|
|
805
|
+
return;
|
|
705
806
|
}
|
|
706
|
-
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
dragItem.style.transform = `translateY(${dy}px)`;
|
|
810
|
+
|
|
811
|
+
const cursorY = ev.clientY;
|
|
812
|
+
let newIdx = startIdx;
|
|
813
|
+
for (let i = 0; i < itemRects.length; i++) {
|
|
814
|
+
const mid = itemRects[i].top + itemRects[i].height / 2;
|
|
815
|
+
if (cursorY > mid) newIdx = i;
|
|
816
|
+
}
|
|
817
|
+
newIdx = Math.max(0, Math.min(items.length - 1, newIdx));
|
|
818
|
+
|
|
819
|
+
if (newIdx !== currentIdx) {
|
|
820
|
+
currentIdx = newIdx;
|
|
821
|
+
items.forEach((it, i) => {
|
|
822
|
+
if (it === dragItem) return;
|
|
823
|
+
if (currentIdx > startIdx && i > startIdx && i <= currentIdx) {
|
|
824
|
+
it.style.transform = `translateY(${-itemHeight}px)`;
|
|
825
|
+
} else if (currentIdx < startIdx && i >= currentIdx && i < startIdx) {
|
|
826
|
+
it.style.transform = `translateY(${itemHeight}px)`;
|
|
827
|
+
} else {
|
|
828
|
+
it.style.transform = "";
|
|
829
|
+
}
|
|
830
|
+
});
|
|
707
831
|
}
|
|
708
832
|
};
|
|
709
833
|
|
|
710
834
|
const onUp = () => {
|
|
711
|
-
if (dragItem) dragItem.style.opacity = "1";
|
|
712
|
-
dragItem = null;
|
|
713
835
|
document.removeEventListener("mousemove", onMove);
|
|
714
836
|
document.removeEventListener("mouseup", onUp);
|
|
715
837
|
|
|
716
|
-
|
|
838
|
+
if (!isDragging) {
|
|
839
|
+
// Was a click — navigate to module
|
|
840
|
+
scrollPreviewToModule(moduleName);
|
|
841
|
+
highlightModuleItem(moduleName);
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
dragItem.classList.remove("module-item--dragging");
|
|
846
|
+
dragItem.style.transform = "";
|
|
847
|
+
items.forEach((it) => {
|
|
848
|
+
it.classList.remove("module-item--placeholder");
|
|
849
|
+
it.style.transform = "";
|
|
850
|
+
});
|
|
851
|
+
|
|
852
|
+
if (currentIdx !== startIdx) {
|
|
853
|
+
if (currentIdx < startIdx) {
|
|
854
|
+
container.insertBefore(dragItem, items[currentIdx]);
|
|
855
|
+
} else {
|
|
856
|
+
const ref = items[currentIdx].nextSibling;
|
|
857
|
+
container.insertBefore(dragItem, ref);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
717
861
|
const newOrder = [...container.querySelectorAll(".module-item")].map(
|
|
718
862
|
(el) => el.dataset.module
|
|
719
863
|
);
|
package/ui/dashboard.js
CHANGED
|
@@ -32,6 +32,7 @@ async function showDashboard(themeName) {
|
|
|
32
32
|
// Hide other screens
|
|
33
33
|
setupScreen.classList.add("hidden");
|
|
34
34
|
document.getElementById("setup-topbar").classList.add("hidden");
|
|
35
|
+
document.getElementById("project-rail")?.classList.remove("project-rail--expanded");
|
|
35
36
|
appScreen.classList.add("hidden");
|
|
36
37
|
dashboardScreen.classList.remove("hidden");
|
|
37
38
|
|
|
@@ -209,6 +210,12 @@ function renderBrandAssets(assets) {
|
|
|
209
210
|
bvIcon.textContent = "+";
|
|
210
211
|
bvIcon.classList.remove("brand-asset-upload__icon--done");
|
|
211
212
|
}
|
|
213
|
+
|
|
214
|
+
// Humanify toggle
|
|
215
|
+
const humanifyCheckbox = document.getElementById("humanify-checkbox");
|
|
216
|
+
if (humanifyCheckbox) {
|
|
217
|
+
humanifyCheckbox.checked = assets.humanify !== false;
|
|
218
|
+
}
|
|
212
219
|
}
|
|
213
220
|
|
|
214
221
|
// ---------------------------------------------------------------------------
|
|
@@ -381,3 +388,15 @@ document.getElementById("brand-upload-styleguide").querySelector("input").addEve
|
|
|
381
388
|
document.getElementById("brand-upload-brandvoice").querySelector("input").addEventListener("change", (e) => {
|
|
382
389
|
if (e.target.files[0]) handleBrandFileSelected("brandvoice", e.target.files[0]);
|
|
383
390
|
});
|
|
391
|
+
|
|
392
|
+
// Humanify toggle
|
|
393
|
+
const humanifyCheckbox = document.getElementById("humanify-checkbox");
|
|
394
|
+
if (humanifyCheckbox) {
|
|
395
|
+
humanifyCheckbox.addEventListener("change", async (e) => {
|
|
396
|
+
await fetch("/api/brand-assets", {
|
|
397
|
+
method: "POST",
|
|
398
|
+
headers: { "Content-Type": "application/json" },
|
|
399
|
+
body: JSON.stringify({ type: "humanify", content: e.target.checked ? "on" : "off" }),
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
}
|
package/ui/field-editor.js
CHANGED
|
@@ -2,21 +2,23 @@
|
|
|
2
2
|
* Field editor sidebar — edit module field values with live preview.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
const editorEl = document.getElementById("field-editor");
|
|
6
5
|
const editorTitle = document.getElementById("field-editor-title");
|
|
7
6
|
const editorContent = document.getElementById("field-editor-content");
|
|
8
|
-
const editorClose = document.getElementById("field-editor-close");
|
|
9
7
|
|
|
10
8
|
let currentEditModule = null;
|
|
11
9
|
|
|
12
10
|
// ---------------------------------------------------------------------------
|
|
13
|
-
// Open / close
|
|
11
|
+
// Open / close (integrated with module slideout)
|
|
14
12
|
// ---------------------------------------------------------------------------
|
|
15
13
|
|
|
16
14
|
async function openFieldEditor(moduleName) {
|
|
17
15
|
currentEditModule = moduleName;
|
|
18
16
|
editorTitle.textContent = moduleName;
|
|
19
|
-
|
|
17
|
+
|
|
18
|
+
// Switch slideout to editor view
|
|
19
|
+
if (typeof showEditorView === "function") {
|
|
20
|
+
showEditorView(moduleName);
|
|
21
|
+
}
|
|
20
22
|
|
|
21
23
|
// Fetch module data
|
|
22
24
|
try {
|
|
@@ -36,12 +38,12 @@ async function openFieldEditor(moduleName) {
|
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
function closeFieldEditor() {
|
|
39
|
-
editorEl.classList.remove("open");
|
|
40
41
|
currentEditModule = null;
|
|
42
|
+
if (typeof showModuleListView === "function") {
|
|
43
|
+
showModuleListView();
|
|
44
|
+
}
|
|
41
45
|
}
|
|
42
46
|
|
|
43
|
-
editorClose.addEventListener("click", closeFieldEditor);
|
|
44
|
-
|
|
45
47
|
// ---------------------------------------------------------------------------
|
|
46
48
|
// Render field form
|
|
47
49
|
// ---------------------------------------------------------------------------
|
package/ui/index.html
CHANGED
|
@@ -11,6 +11,29 @@
|
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
13
13
|
|
|
14
|
+
<!-- ============================================================ -->
|
|
15
|
+
<!-- PROJECT RAIL — persistent thin sidebar (Discord-style) -->
|
|
16
|
+
<!-- ============================================================ -->
|
|
17
|
+
<aside class="project-rail project-rail--expanded" id="project-rail">
|
|
18
|
+
<div class="project-rail__header">
|
|
19
|
+
<span class="project-rail__title">Projects</span>
|
|
20
|
+
<span class="project-rail__count" id="rail-project-count">0</span>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="project-rail__items" id="project-rail-items"></div>
|
|
23
|
+
<button class="project-rail__add" id="project-rail-add" title="New project">+</button>
|
|
24
|
+
<div class="project-rail__footer">
|
|
25
|
+
<button class="project-rail__settings-btn" id="btn-setup-settings">
|
|
26
|
+
<svg width="14" height="14" viewBox="0 0 18 18" fill="none"><path d="M7.5 1.5h3l.4 2.1a5.5 5.5 0 0 1 1.3.7l2-.8 1.5 2.6-1.6 1.3a5.5 5.5 0 0 1 0 1.5l1.6 1.3-1.5 2.6-2-.8a5.5 5.5 0 0 1-1.3.7l-.4 2.1h-3l-.4-2.1a5.5 5.5 0 0 1-1.3-.7l-2 .8-1.5-2.6 1.6-1.3a5.5 5.5 0 0 1 0-1.5L2.3 6.1l1.5-2.6 2 .8a5.5 5.5 0 0 1 1.3-.7L7.5 1.5Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><circle cx="9" cy="9" r="2" stroke="currentColor" stroke-width="1.5"/></svg>
|
|
27
|
+
<span class="project-rail__settings-label">Settings</span>
|
|
28
|
+
</button>
|
|
29
|
+
</div>
|
|
30
|
+
</aside>
|
|
31
|
+
|
|
32
|
+
<!-- Tooltip element (positioned via JS) -->
|
|
33
|
+
<div class="project-rail__tooltip" id="project-rail-tooltip"></div>
|
|
34
|
+
|
|
35
|
+
<div class="app-body" id="app-body">
|
|
36
|
+
|
|
14
37
|
<!-- ============================================================ -->
|
|
15
38
|
<!-- SETUP SCREEN — shown until a session is created -->
|
|
16
39
|
<!-- ============================================================ -->
|
|
@@ -21,24 +44,6 @@
|
|
|
21
44
|
</div>
|
|
22
45
|
</div>
|
|
23
46
|
<div class="setup" id="setup-screen">
|
|
24
|
-
<!-- Left sidebar: project list -->
|
|
25
|
-
<aside class="setup-sidebar" id="setup-sidebar">
|
|
26
|
-
<div class="setup-sidebar__header">
|
|
27
|
-
<span class="setup-sidebar__title">Projects</span>
|
|
28
|
-
<span class="setup-sidebar__count" id="sidebar-project-count">0</span>
|
|
29
|
-
</div>
|
|
30
|
-
<div class="setup-sidebar__list" id="sidebar-project-list">
|
|
31
|
-
<!-- Populated by setup.js -->
|
|
32
|
-
</div>
|
|
33
|
-
<div class="setup-sidebar__footer">
|
|
34
|
-
<button class="setup-sidebar__settings-btn" id="btn-setup-settings">
|
|
35
|
-
<svg width="14" height="14" viewBox="0 0 18 18" fill="none"><path d="M7.5 1.5h3l.4 2.1a5.5 5.5 0 0 1 1.3.7l2-.8 1.5 2.6-1.6 1.3a5.5 5.5 0 0 1 0 1.5l1.6 1.3-1.5 2.6-2-.8a5.5 5.5 0 0 1-1.3.7l-.4 2.1h-3l-.4-2.1a5.5 5.5 0 0 1-1.3-.7l-2 .8-1.5-2.6 1.6-1.3a5.5 5.5 0 0 1 0-1.5L2.3 6.1l1.5-2.6 2 .8a5.5 5.5 0 0 1 1.3-.7L7.5 1.5Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><circle cx="9" cy="9" r="2" stroke="currentColor" stroke-width="1.5"/></svg>
|
|
36
|
-
Settings
|
|
37
|
-
</button>
|
|
38
|
-
</div>
|
|
39
|
-
</aside>
|
|
40
|
-
|
|
41
|
-
<!-- Right side: main content -->
|
|
42
47
|
<div class="setup__main">
|
|
43
48
|
<div class="setup__container">
|
|
44
49
|
<div class="setup__symbol">✦</div>
|
|
@@ -153,6 +158,14 @@
|
|
|
153
158
|
<span class="dashboard__section-hint">Optional — injected into AI prompts</span>
|
|
154
159
|
</div>
|
|
155
160
|
<div class="dashboard__brand-assets" id="dashboard-brand-assets">
|
|
161
|
+
<div class="brand-asset-toggle" id="brand-toggle-humanify">
|
|
162
|
+
<label class="brand-asset-toggle__switch">
|
|
163
|
+
<input type="checkbox" id="humanify-checkbox" checked>
|
|
164
|
+
<span class="brand-asset-toggle__slider"></span>
|
|
165
|
+
</label>
|
|
166
|
+
<span class="brand-asset-toggle__label">Humanify</span>
|
|
167
|
+
<span class="brand-asset-toggle__tooltip" data-tooltip="Strips AI-sounding copy: removes em dashes, banned words like 'delve' and 'leverage', cliché openers, and forced enthusiasm. Makes your landing page read like a human wrote it.">?</span>
|
|
168
|
+
</div>
|
|
156
169
|
<label class="brand-asset-upload" id="brand-upload-styleguide">
|
|
157
170
|
<input type="file" accept=".md,.txt" hidden>
|
|
158
171
|
<span class="brand-asset-upload__icon" id="brand-icon-styleguide">+</span>
|
|
@@ -277,14 +290,33 @@
|
|
|
277
290
|
|
|
278
291
|
<div class="layout">
|
|
279
292
|
<aside class="panel panel--left" id="panel-left">
|
|
280
|
-
<div class="module-
|
|
281
|
-
<
|
|
293
|
+
<div class="module-bar" id="module-bar">
|
|
294
|
+
<button class="module-bar__btn" id="btn-modules">
|
|
295
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>
|
|
282
296
|
<span>Modules</span>
|
|
283
|
-
<span class="module-
|
|
284
|
-
|
|
297
|
+
<span class="module-bar__count" id="module-count">0</span>
|
|
298
|
+
</button>
|
|
299
|
+
</div>
|
|
300
|
+
|
|
301
|
+
<div class="module-slideout" id="module-slideout">
|
|
302
|
+
<div class="module-slideout__view" id="module-list-view">
|
|
303
|
+
<div class="module-slideout__header">
|
|
304
|
+
<span class="module-slideout__title">Modules</span>
|
|
305
|
+
<span class="module-slideout__count" id="slideout-module-count">0</span>
|
|
306
|
+
<button class="module-slideout__add" id="btn-add-module" title="Add module from library">+</button>
|
|
307
|
+
<button class="module-slideout__close" id="module-slideout-close">×</button>
|
|
308
|
+
</div>
|
|
309
|
+
<div class="module-library-dropdown hidden" id="module-library-dropdown"></div>
|
|
310
|
+
<div class="module-slideout__items" id="module-items"></div>
|
|
311
|
+
</div>
|
|
312
|
+
<div class="module-slideout__view hidden" id="module-editor-view">
|
|
313
|
+
<div class="module-slideout__header">
|
|
314
|
+
<button class="module-slideout__back" id="field-editor-back">←</button>
|
|
315
|
+
<span class="module-slideout__title" id="field-editor-title">Fields</span>
|
|
316
|
+
<button class="module-slideout__close" id="field-editor-close">×</button>
|
|
317
|
+
</div>
|
|
318
|
+
<div class="field-editor__content" id="field-editor-content"></div>
|
|
285
319
|
</div>
|
|
286
|
-
<div class="module-list__items" id="module-items"></div>
|
|
287
|
-
<div class="module-library-dropdown hidden" id="module-library-dropdown"></div>
|
|
288
320
|
</div>
|
|
289
321
|
|
|
290
322
|
<div class="chat">
|
|
@@ -337,13 +369,6 @@
|
|
|
337
369
|
<iframe id="preview-frame" class="browser-chrome__frame" sandbox="allow-scripts allow-same-origin"></iframe>
|
|
338
370
|
</div>
|
|
339
371
|
</div>
|
|
340
|
-
<aside class="field-editor" id="field-editor">
|
|
341
|
-
<div class="field-editor__header">
|
|
342
|
-
<h3 id="field-editor-title">Fields</h3>
|
|
343
|
-
<button class="field-editor__close" id="field-editor-close">×</button>
|
|
344
|
-
</div>
|
|
345
|
-
<div class="field-editor__content" id="field-editor-content"></div>
|
|
346
|
-
</aside>
|
|
347
372
|
<aside class="history-panel hidden" id="history-panel">
|
|
348
373
|
<div class="history-panel__header">
|
|
349
374
|
<h3>Version History</h3>
|
|
@@ -392,6 +417,8 @@
|
|
|
392
417
|
</div>
|
|
393
418
|
</div>
|
|
394
419
|
|
|
420
|
+
</div><!-- /app-body -->
|
|
421
|
+
|
|
395
422
|
<script src="/dialog.js"></script>
|
|
396
423
|
<script src="/setup.js"></script>
|
|
397
424
|
<script src="/dashboard.js"></script>
|