clay-server 2.23.1 → 2.24.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/build-user-env.js +6 -0
- package/lib/daemon.js +13 -0
- package/lib/ipv4-only.js +39 -0
- package/lib/project.js +333 -42
- package/lib/public/app.js +119 -69
- package/lib/public/claude-code-avatar.png +0 -0
- package/lib/public/css/debate.css +35 -1
- package/lib/public/css/filebrowser.css +2 -1
- package/lib/public/css/icon-strip.css +23 -0
- package/lib/public/css/input.css +66 -0
- package/lib/public/css/loop.css +0 -2
- package/lib/public/css/mates.css +113 -6
- package/lib/public/css/mention.css +26 -1
- package/lib/public/css/messages.css +97 -0
- package/lib/public/css/overlays.css +0 -4
- package/lib/public/css/server-settings.css +53 -0
- package/lib/public/css/session-search.css +1 -1
- package/lib/public/css/sidebar.css +26 -2
- package/lib/public/index.html +53 -13
- package/lib/public/modules/debate.js +158 -1
- package/lib/public/modules/filebrowser.js +11 -0
- package/lib/public/modules/input.js +20 -2
- package/lib/public/modules/markdown.js +2 -2
- package/lib/public/modules/mention.js +82 -32
- package/lib/public/modules/notifications.js +5 -1
- package/lib/public/modules/session-search.js +5 -5
- package/lib/public/modules/sidebar.js +39 -26
- package/lib/public/modules/theme.js +30 -0
- package/lib/public/modules/user-settings.js +61 -12
- package/lib/sdk-bridge.js +83 -78
- package/lib/sdk-worker.js +83 -3
- package/lib/server.js +93 -3
- package/lib/session-search.js +40 -5
- package/lib/sessions.js +2 -2
- package/lib/users.js +38 -0
- package/package.json +1 -1
package/lib/public/app.js
CHANGED
|
@@ -77,6 +77,9 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
77
77
|
var cachedMatesList = []; // Cached list of mates for user strip
|
|
78
78
|
var cachedAvailableBuiltins = []; // Deleted built-in mates available for re-add
|
|
79
79
|
|
|
80
|
+
// Claude Code avatar (mascot image served from public root)
|
|
81
|
+
var CLAUDE_CODE_AVATAR = "/claude-code-avatar.png";
|
|
82
|
+
|
|
80
83
|
// --- Mate project switching ---
|
|
81
84
|
var mateProjectSlug = null;
|
|
82
85
|
var savedMainSlug = null; // main project slug saved during mate DM
|
|
@@ -562,14 +565,62 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
562
565
|
if (!ws || ws.readyState !== 1) return;
|
|
563
566
|
// Check mate skill updates before opening mate DM
|
|
564
567
|
if (typeof targetUserId === "string" && targetUserId.indexOf("mate_") === 0) {
|
|
565
|
-
|
|
566
|
-
|
|
568
|
+
showMateOnboarding(function () {
|
|
569
|
+
requireClayMateInterview(function () {
|
|
570
|
+
ws.send(JSON.stringify({ type: "dm_open", targetUserId: targetUserId }));
|
|
571
|
+
});
|
|
567
572
|
});
|
|
568
573
|
return;
|
|
569
574
|
}
|
|
570
575
|
ws.send(JSON.stringify({ type: "dm_open", targetUserId: targetUserId }));
|
|
571
576
|
}
|
|
572
577
|
|
|
578
|
+
var MATE_ONBOARDING_KEY = "clay-mate-onboarding-shown";
|
|
579
|
+
|
|
580
|
+
function showMateOnboarding(callback) {
|
|
581
|
+
try {
|
|
582
|
+
if (localStorage.getItem(MATE_ONBOARDING_KEY)) { callback(); return; }
|
|
583
|
+
} catch (e) {}
|
|
584
|
+
|
|
585
|
+
var overlay = document.createElement("div");
|
|
586
|
+
overlay.className = "mate-onboarding-overlay";
|
|
587
|
+
overlay.innerHTML =
|
|
588
|
+
'<div class="mate-onboarding-card">' +
|
|
589
|
+
'<h2 class="mate-onboarding-title">Meet your Mates</h2>' +
|
|
590
|
+
'<p class="mate-onboarding-desc">' +
|
|
591
|
+
'Mates are AI teammates powered by your Claude Code.<br>Each one has a distinct role, builds its own knowledge, and gets sharper over time.' +
|
|
592
|
+
'</p>' +
|
|
593
|
+
'<ul class="mate-onboarding-features">' +
|
|
594
|
+
'<li><span class="mate-onboarding-bullet">\uD83C\uDFAD</span><div><strong>Specialized personas</strong><br><span class="mate-onboarding-sub">Architect, reviewer, researcher, chief of staff, and more</span></div></li>' +
|
|
595
|
+
'<li><span class="mate-onboarding-bullet">\uD83D\uDD04</span><div><strong>Persistent memory</strong><br><span class="mate-onboarding-sub">Every conversation makes them smarter about you and your work</span></div></li>' +
|
|
596
|
+
'<li><span class="mate-onboarding-bullet">\uD83D\uDCAC</span><div><strong>Shared context across the team</strong><br><span class="mate-onboarding-sub">What one mate learns, the others can reference</span></div></li>' +
|
|
597
|
+
'<li><span class="mate-onboarding-bullet">\uD83D\uDCDA</span><div><strong>Self-growing knowledge base</strong><br><span class="mate-onboarding-sub">They accumulate notes, decisions, and observations on their own</span></div></li>' +
|
|
598
|
+
'</ul>' +
|
|
599
|
+
'<button class="mate-onboarding-btn">Let\u2019s go</button>' +
|
|
600
|
+
'</div>';
|
|
601
|
+
|
|
602
|
+
document.body.appendChild(overlay);
|
|
603
|
+
|
|
604
|
+
// Animate in
|
|
605
|
+
requestAnimationFrame(function () {
|
|
606
|
+
overlay.classList.add("visible");
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
function dismissOnboarding() {
|
|
610
|
+
try { localStorage.setItem(MATE_ONBOARDING_KEY, "1"); } catch (e) {}
|
|
611
|
+
fetch("/api/user/mate-onboarded", { method: "POST" }).catch(function () {});
|
|
612
|
+
overlay.classList.remove("visible");
|
|
613
|
+
setTimeout(function () { overlay.remove(); callback(); }, 200);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
overlay.querySelector(".mate-onboarding-btn").addEventListener("click", dismissOnboarding);
|
|
617
|
+
|
|
618
|
+
// Click outside to dismiss
|
|
619
|
+
overlay.addEventListener("click", function (e) {
|
|
620
|
+
if (e.target === overlay) dismissOnboarding();
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
|
|
573
624
|
function enterDmMode(key, targetUser, messages) {
|
|
574
625
|
console.log("[DEBUG enterDmMode] key=" + key, "isMate=" + (targetUser && targetUser.isMate), "messages=" + (messages ? messages.length : 0));
|
|
575
626
|
// Clean up previous DM/mate state before entering new one
|
|
@@ -1289,12 +1340,13 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1289
1340
|
if (msg.dmFavorites) cachedDmFavorites = msg.dmFavorites;
|
|
1290
1341
|
if (msg.dmConversations) cachedDmConversations = msg.dmConversations;
|
|
1291
1342
|
renderUserStrip(msg.allUsers, cachedOnlineIds, myUserId, cachedDmFavorites, cachedDmConversations, dmUnread, dmRemovedUsers, cachedMatesList);
|
|
1292
|
-
// Update my info in body.dataset if in mate DM (fixes stale data after refresh)
|
|
1293
|
-
if (document.body.classList.contains("mate-dm-active")) {
|
|
1343
|
+
// Update my info in body.dataset if in mate DM or wide view (fixes stale data after refresh)
|
|
1344
|
+
if (document.body.classList.contains("mate-dm-active") || document.body.classList.contains("wide-view")) {
|
|
1294
1345
|
var refreshedMyUser = cachedAllUsers.find(function (u) { return u.id === myUserId; });
|
|
1295
1346
|
if (refreshedMyUser) {
|
|
1296
|
-
document.body.dataset.myDisplayName = refreshedMyUser.displayName || "";
|
|
1347
|
+
document.body.dataset.myDisplayName = refreshedMyUser.displayName || refreshedMyUser.username || "";
|
|
1297
1348
|
document.body.dataset.myAvatarUrl = userAvatarUrl(refreshedMyUser, 36);
|
|
1349
|
+
try { localStorage.setItem("clay_my_user", JSON.stringify({ displayName: refreshedMyUser.displayName, username: refreshedMyUser.username, avatarStyle: refreshedMyUser.avatarStyle, avatarSeed: refreshedMyUser.avatarSeed, avatarCustom: refreshedMyUser.avatarCustom })); } catch(e) {}
|
|
1298
1350
|
}
|
|
1299
1351
|
}
|
|
1300
1352
|
// Render my avatar (always present, hidden behind user-island)
|
|
@@ -1444,6 +1496,10 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1444
1496
|
$("paste-modal").querySelector(".paste-modal-close").addEventListener("click", function() {
|
|
1445
1497
|
$("paste-modal").classList.add("hidden");
|
|
1446
1498
|
});
|
|
1499
|
+
$("paste-modal").querySelector(".paste-modal-copy").addEventListener("click", function() {
|
|
1500
|
+
var body = $("paste-modal-body");
|
|
1501
|
+
if (body) copyToClipboard(body.textContent, "Copied to clipboard");
|
|
1502
|
+
});
|
|
1447
1503
|
$("mermaid-modal").querySelector(".confirm-backdrop").addEventListener("click", closeMermaidModal);
|
|
1448
1504
|
$("mermaid-modal").querySelector(".mermaid-modal-btn[title='Close']").addEventListener("click", closeMermaidModal);
|
|
1449
1505
|
$("image-modal").querySelector(".confirm-backdrop").addEventListener("click", closeImageModal);
|
|
@@ -2868,38 +2924,38 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
2868
2924
|
}
|
|
2869
2925
|
|
|
2870
2926
|
|
|
2871
|
-
//
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
div.appendChild(avi);
|
|
2927
|
+
// Always render avatar + header structure (CSS controls visibility)
|
|
2928
|
+
var _myU = cachedAllUsers.find(function (u) { return u.id === myUserId; });
|
|
2929
|
+
if (!_myU) {
|
|
2930
|
+
try { _myU = JSON.parse(localStorage.getItem("clay_my_user") || "null"); } catch(e) {}
|
|
2931
|
+
}
|
|
2877
2932
|
|
|
2878
|
-
|
|
2879
|
-
|
|
2933
|
+
var avi = document.createElement("img");
|
|
2934
|
+
avi.className = "dm-bubble-avatar dm-bubble-avatar-me";
|
|
2935
|
+
avi.src = document.body.dataset.myAvatarUrl || userAvatarUrl(_myU || { id: myUserId }, 36);
|
|
2936
|
+
div.appendChild(avi);
|
|
2880
2937
|
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
}
|
|
2938
|
+
var contentWrap = document.createElement("div");
|
|
2939
|
+
contentWrap.className = "dm-bubble-content";
|
|
2940
|
+
|
|
2941
|
+
var header = document.createElement("div");
|
|
2942
|
+
header.className = "dm-bubble-header";
|
|
2943
|
+
var myDisplayName = document.body.dataset.myDisplayName || "";
|
|
2944
|
+
if (!myDisplayName) {
|
|
2945
|
+
myDisplayName = (_myU && (_myU.displayName || _myU.username)) || "Me";
|
|
2946
|
+
}
|
|
2947
|
+
var nameSpan = document.createElement("span");
|
|
2948
|
+
nameSpan.className = "dm-bubble-name";
|
|
2949
|
+
nameSpan.textContent = myDisplayName;
|
|
2950
|
+
header.appendChild(nameSpan);
|
|
2951
|
+
var timeSpan = document.createElement("span");
|
|
2952
|
+
timeSpan.className = "dm-bubble-time";
|
|
2953
|
+
var nowH = new Date();
|
|
2954
|
+
timeSpan.textContent = String(nowH.getHours()).padStart(2, "0") + ":" + String(nowH.getMinutes()).padStart(2, "0");
|
|
2955
|
+
header.appendChild(timeSpan);
|
|
2956
|
+
contentWrap.appendChild(header);
|
|
2957
|
+
contentWrap.appendChild(bubble);
|
|
2958
|
+
div.appendChild(contentWrap);
|
|
2903
2959
|
|
|
2904
2960
|
// Action bar below bubble (icons visible on hover)
|
|
2905
2961
|
var actions = document.createElement("div");
|
|
@@ -2933,40 +2989,34 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
2933
2989
|
currentMsgEl = document.createElement("div");
|
|
2934
2990
|
currentMsgEl.className = "msg-assistant";
|
|
2935
2991
|
currentMsgEl.dataset.turn = turnCounter;
|
|
2936
|
-
//
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
} else {
|
|
2965
|
-
var mdDiv = document.createElement("div");
|
|
2966
|
-
mdDiv.className = "md-content";
|
|
2967
|
-
mdDiv.dir = "auto";
|
|
2968
|
-
currentMsgEl.appendChild(mdDiv);
|
|
2969
|
-
}
|
|
2992
|
+
// Always render avatar + header structure (CSS controls visibility)
|
|
2993
|
+
var _isDm2 = document.body.classList.contains("mate-dm-active") && document.body.dataset.mateAvatarUrl;
|
|
2994
|
+
var avi = document.createElement("img");
|
|
2995
|
+
avi.className = "dm-bubble-avatar dm-bubble-avatar-mate";
|
|
2996
|
+
avi.src = _isDm2 ? document.body.dataset.mateAvatarUrl : CLAUDE_CODE_AVATAR;
|
|
2997
|
+
currentMsgEl.appendChild(avi);
|
|
2998
|
+
|
|
2999
|
+
var contentWrap = document.createElement("div");
|
|
3000
|
+
contentWrap.className = "dm-bubble-content";
|
|
3001
|
+
|
|
3002
|
+
var header = document.createElement("div");
|
|
3003
|
+
header.className = "dm-bubble-header";
|
|
3004
|
+
var nameSpan = document.createElement("span");
|
|
3005
|
+
nameSpan.className = "dm-bubble-name";
|
|
3006
|
+
nameSpan.textContent = _isDm2 ? ((dmTargetUser && dmTargetUser.displayName) || "Mate") : "Claude Code";
|
|
3007
|
+
header.appendChild(nameSpan);
|
|
3008
|
+
var timeSpan = document.createElement("span");
|
|
3009
|
+
timeSpan.className = "dm-bubble-time";
|
|
3010
|
+
var nowA = new Date();
|
|
3011
|
+
timeSpan.textContent = String(nowA.getHours()).padStart(2, "0") + ":" + String(nowA.getMinutes()).padStart(2, "0");
|
|
3012
|
+
header.appendChild(timeSpan);
|
|
3013
|
+
contentWrap.appendChild(header);
|
|
3014
|
+
|
|
3015
|
+
var mdDiv = document.createElement("div");
|
|
3016
|
+
mdDiv.className = "md-content";
|
|
3017
|
+
mdDiv.dir = "auto";
|
|
3018
|
+
contentWrap.appendChild(mdDiv);
|
|
3019
|
+
currentMsgEl.appendChild(contentWrap);
|
|
2970
3020
|
addToMessages(currentMsgEl);
|
|
2971
3021
|
currentFullText = "";
|
|
2972
3022
|
}
|
|
Binary file
|
|
@@ -149,7 +149,6 @@
|
|
|
149
149
|
z-index: 50;
|
|
150
150
|
padding: 6px 16px;
|
|
151
151
|
background: color-mix(in srgb, var(--bg) 92%, transparent);
|
|
152
|
-
backdrop-filter: blur(8px);
|
|
153
152
|
border-bottom: 1px solid var(--border);
|
|
154
153
|
}
|
|
155
154
|
#debate-info-float.hidden { display: none; }
|
|
@@ -577,6 +576,41 @@
|
|
|
577
576
|
background: color-mix(in srgb, var(--accent) 10%, transparent);
|
|
578
577
|
}
|
|
579
578
|
|
|
579
|
+
/* --- Title bar PDF button (matches find-in-session-btn / terminal-toggle-btn pattern) --- */
|
|
580
|
+
#debate-pdf-btn {
|
|
581
|
+
display: flex;
|
|
582
|
+
align-items: center;
|
|
583
|
+
justify-content: center;
|
|
584
|
+
background: none;
|
|
585
|
+
border: 1px solid transparent;
|
|
586
|
+
border-radius: 8px;
|
|
587
|
+
color: var(--text-dimmer);
|
|
588
|
+
cursor: pointer;
|
|
589
|
+
padding: 4px;
|
|
590
|
+
transition: color 0.15s, background 0.15s, border-color 0.15s;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
#debate-pdf-btn .lucide { width: 15px; height: 15px; }
|
|
594
|
+
#debate-pdf-btn:hover { color: var(--text-secondary); background: rgba(var(--overlay-rgb),0.04); border-color: var(--border); }
|
|
595
|
+
#debate-pdf-btn:disabled { opacity: 0.5; cursor: default; }
|
|
596
|
+
|
|
597
|
+
/* --- Ended banner PDF button --- */
|
|
598
|
+
.debate-ended-pdf-btn {
|
|
599
|
+
display: inline-flex;
|
|
600
|
+
align-items: center;
|
|
601
|
+
gap: 4px;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
.debate-ended-pdf-btn svg {
|
|
605
|
+
width: 14px;
|
|
606
|
+
height: 14px;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
.debate-ended-pdf-btn:disabled {
|
|
610
|
+
opacity: 0.5;
|
|
611
|
+
cursor: default;
|
|
612
|
+
}
|
|
613
|
+
|
|
580
614
|
/* --- Error --- */
|
|
581
615
|
.debate-error {
|
|
582
616
|
padding: 8px 20px;
|
|
@@ -57,7 +57,8 @@
|
|
|
57
57
|
display: none;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
#file-panel-refresh.spinning
|
|
60
|
+
#file-panel-refresh.spinning,
|
|
61
|
+
#file-viewer-refresh.spinning { animation: spin-once 0.5s ease; }
|
|
61
62
|
@keyframes spin-once { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
|
|
62
63
|
|
|
63
64
|
/* --- File tree --- */
|
|
@@ -1392,6 +1392,29 @@ select.wt-modal-input {
|
|
|
1392
1392
|
|
|
1393
1393
|
/* --- Per-project presence avatars --- */
|
|
1394
1394
|
/* --- Mobile: hide icon strip --- */
|
|
1395
|
+
/* --- Skeleton loading placeholders --- */
|
|
1396
|
+
@keyframes skeleton-shimmer {
|
|
1397
|
+
0% { opacity: 0.15; }
|
|
1398
|
+
50% { opacity: 0.25; }
|
|
1399
|
+
100% { opacity: 0.15; }
|
|
1400
|
+
}
|
|
1401
|
+
.skeleton-icon-strip-item {
|
|
1402
|
+
width: 38px;
|
|
1403
|
+
height: 38px;
|
|
1404
|
+
border-radius: 12px;
|
|
1405
|
+
background: var(--text-muted, #888);
|
|
1406
|
+
margin: 5px auto;
|
|
1407
|
+
animation: skeleton-shimmer 1.5s ease-in-out infinite;
|
|
1408
|
+
}
|
|
1409
|
+
.skeleton-icon-strip-user {
|
|
1410
|
+
width: 34px;
|
|
1411
|
+
height: 34px;
|
|
1412
|
+
border-radius: 50%;
|
|
1413
|
+
background: var(--text-muted, #888);
|
|
1414
|
+
margin: 4px auto;
|
|
1415
|
+
animation: skeleton-shimmer 1.5s ease-in-out infinite;
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1395
1418
|
@media (max-width: 768px) {
|
|
1396
1419
|
#icon-strip {
|
|
1397
1420
|
display: none;
|
package/lib/public/css/input.css
CHANGED
|
@@ -120,6 +120,13 @@
|
|
|
120
120
|
color: var(--text);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
.paste-modal-actions {
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
gap: 4px;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.paste-modal-copy,
|
|
123
130
|
.paste-modal-close {
|
|
124
131
|
display: flex;
|
|
125
132
|
align-items: center;
|
|
@@ -133,6 +140,7 @@
|
|
|
133
140
|
transition: color 0.15s, background 0.15s;
|
|
134
141
|
}
|
|
135
142
|
|
|
143
|
+
.paste-modal-copy:hover,
|
|
136
144
|
.paste-modal-close:hover { color: var(--text); background: rgba(var(--overlay-rgb), 0.06); }
|
|
137
145
|
|
|
138
146
|
.paste-modal-body {
|
|
@@ -364,6 +372,64 @@
|
|
|
364
372
|
#attach-image-btn:hover,
|
|
365
373
|
#schedule-btn:hover { background: rgba(var(--overlay-rgb), 0.06); color: var(--text); }
|
|
366
374
|
|
|
375
|
+
#ask-mate-btn {
|
|
376
|
+
height: 28px;
|
|
377
|
+
padding: 0 10px;
|
|
378
|
+
border-radius: 10px;
|
|
379
|
+
border: 1px solid transparent;
|
|
380
|
+
background:
|
|
381
|
+
linear-gradient(var(--bg, #282a36), var(--bg, #282a36)) padding-box,
|
|
382
|
+
linear-gradient(135deg, #4ecdc4 0%, #4ecdc4 25%, #556bf7, #a855f7, #f857a6, #ff6b6b) border-box;
|
|
383
|
+
color: transparent;
|
|
384
|
+
cursor: pointer;
|
|
385
|
+
display: flex;
|
|
386
|
+
align-items: center;
|
|
387
|
+
gap: 5px;
|
|
388
|
+
font-family: 'Nunito', sans-serif;
|
|
389
|
+
font-size: 13px;
|
|
390
|
+
font-weight: 800;
|
|
391
|
+
letter-spacing: 0.2px;
|
|
392
|
+
transition: transform 0.1s, box-shadow 0.3s, border-color 0.3s;
|
|
393
|
+
touch-action: manipulation;
|
|
394
|
+
position: relative;
|
|
395
|
+
overflow: hidden;
|
|
396
|
+
z-index: 0;
|
|
397
|
+
}
|
|
398
|
+
#ask-mate-btn::before {
|
|
399
|
+
content: "";
|
|
400
|
+
position: absolute;
|
|
401
|
+
inset: 0;
|
|
402
|
+
background: linear-gradient(135deg, #4ecdc4 0%, #4ecdc4 32%, #556bf7 34%, #556bf7 50%, #a855f7 52%, #a855f7 68%, #f857a6 70%, #f857a6 84%, #ff6b6b 86%, #ff6b6b 100%);
|
|
403
|
+
border-radius: inherit;
|
|
404
|
+
opacity: 0;
|
|
405
|
+
transform: scale(0.3);
|
|
406
|
+
transition: opacity 0.3s ease, transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
407
|
+
z-index: -1;
|
|
408
|
+
}
|
|
409
|
+
.ask-mate-label {
|
|
410
|
+
white-space: nowrap;
|
|
411
|
+
background: linear-gradient(135deg, #4ecdc4 0%, #4ecdc4 25%, #556bf7, #a855f7, #f857a6, #ff6b6b);
|
|
412
|
+
-webkit-background-clip: text;
|
|
413
|
+
background-clip: text;
|
|
414
|
+
-webkit-text-fill-color: transparent;
|
|
415
|
+
transition: opacity 0.2s;
|
|
416
|
+
}
|
|
417
|
+
#ask-mate-btn:hover::before {
|
|
418
|
+
opacity: 1;
|
|
419
|
+
transform: scale(1);
|
|
420
|
+
}
|
|
421
|
+
#ask-mate-btn:hover {
|
|
422
|
+
border-color: transparent;
|
|
423
|
+
background: transparent;
|
|
424
|
+
transform: translateY(-1px);
|
|
425
|
+
box-shadow: 0 2px 12px rgba(148, 130, 247, 0.4);
|
|
426
|
+
}
|
|
427
|
+
#ask-mate-btn:hover .ask-mate-label {
|
|
428
|
+
background: none;
|
|
429
|
+
-webkit-text-fill-color: #fff;
|
|
430
|
+
}
|
|
431
|
+
#ask-mate-btn:active { transform: translateY(-1px) scale(0.95); }
|
|
432
|
+
|
|
367
433
|
#send-btn {
|
|
368
434
|
flex-shrink: 0;
|
|
369
435
|
width: 36px;
|
package/lib/public/css/loop.css
CHANGED
package/lib/public/css/mates.css
CHANGED
|
@@ -63,8 +63,6 @@
|
|
|
63
63
|
position: absolute;
|
|
64
64
|
inset: 0;
|
|
65
65
|
background: rgba(var(--shadow-rgb, 0,0,0), 0.5);
|
|
66
|
-
backdrop-filter: blur(2px);
|
|
67
|
-
-webkit-backdrop-filter: blur(2px);
|
|
68
66
|
}
|
|
69
67
|
.mate-wizard-card {
|
|
70
68
|
position: relative;
|
|
@@ -860,6 +858,103 @@ body.mate-dm-active #layout.sidebar-collapsed .mate-collapsed-info {
|
|
|
860
858
|
background: #c0392b;
|
|
861
859
|
}
|
|
862
860
|
|
|
861
|
+
/* --- Mate onboarding modal --- */
|
|
862
|
+
.mate-onboarding-overlay {
|
|
863
|
+
position: fixed;
|
|
864
|
+
inset: 0;
|
|
865
|
+
background: rgba(0,0,0,0);
|
|
866
|
+
z-index: 999;
|
|
867
|
+
display: flex;
|
|
868
|
+
align-items: center;
|
|
869
|
+
justify-content: center;
|
|
870
|
+
transition: background 0.2s ease;
|
|
871
|
+
}
|
|
872
|
+
.mate-onboarding-overlay.visible {
|
|
873
|
+
background: rgba(0,0,0,0.45);
|
|
874
|
+
}
|
|
875
|
+
.mate-onboarding-card {
|
|
876
|
+
background: var(--bg-primary, #fff);
|
|
877
|
+
border: 1px solid var(--border-subtle);
|
|
878
|
+
border-radius: 16px;
|
|
879
|
+
padding: 32px 36px;
|
|
880
|
+
max-width: 400px;
|
|
881
|
+
width: 90%;
|
|
882
|
+
box-shadow: 0 12px 48px rgba(0,0,0,0.2);
|
|
883
|
+
text-align: center;
|
|
884
|
+
transform: translateY(20px) scale(0.96);
|
|
885
|
+
opacity: 0;
|
|
886
|
+
transition: transform 0.25s ease, opacity 0.25s ease;
|
|
887
|
+
}
|
|
888
|
+
.mate-onboarding-overlay.visible .mate-onboarding-card {
|
|
889
|
+
transform: translateY(0) scale(1);
|
|
890
|
+
opacity: 1;
|
|
891
|
+
}
|
|
892
|
+
.mate-onboarding-icon {
|
|
893
|
+
font-size: 40px;
|
|
894
|
+
margin-bottom: 8px;
|
|
895
|
+
}
|
|
896
|
+
.mate-onboarding-title {
|
|
897
|
+
font-size: 20px;
|
|
898
|
+
font-weight: 700;
|
|
899
|
+
color: var(--text);
|
|
900
|
+
margin: 0 0 10px;
|
|
901
|
+
}
|
|
902
|
+
.mate-onboarding-desc {
|
|
903
|
+
font-size: 14px;
|
|
904
|
+
color: var(--text-secondary);
|
|
905
|
+
line-height: 1.5;
|
|
906
|
+
margin: 0 0 18px;
|
|
907
|
+
}
|
|
908
|
+
.mate-onboarding-features {
|
|
909
|
+
list-style: none;
|
|
910
|
+
padding: 0;
|
|
911
|
+
margin: 0 0 24px;
|
|
912
|
+
text-align: left;
|
|
913
|
+
}
|
|
914
|
+
.mate-onboarding-features li {
|
|
915
|
+
font-size: 13px;
|
|
916
|
+
color: var(--text);
|
|
917
|
+
padding: 8px 0;
|
|
918
|
+
display: flex;
|
|
919
|
+
align-items: flex-start;
|
|
920
|
+
gap: 10px;
|
|
921
|
+
line-height: 1.4;
|
|
922
|
+
}
|
|
923
|
+
.mate-onboarding-sub {
|
|
924
|
+
color: var(--text-muted);
|
|
925
|
+
font-size: 12px;
|
|
926
|
+
}
|
|
927
|
+
.mate-onboarding-bullet {
|
|
928
|
+
font-size: 16px;
|
|
929
|
+
flex-shrink: 0;
|
|
930
|
+
width: 24px;
|
|
931
|
+
text-align: center;
|
|
932
|
+
}
|
|
933
|
+
.mate-onboarding-note {
|
|
934
|
+
font-size: 11px;
|
|
935
|
+
color: var(--text-muted);
|
|
936
|
+
text-align: center;
|
|
937
|
+
margin: 0 0 16px;
|
|
938
|
+
}
|
|
939
|
+
.mate-onboarding-btn {
|
|
940
|
+
width: 100%;
|
|
941
|
+
padding: 10px 0;
|
|
942
|
+
border: none;
|
|
943
|
+
border-radius: 10px;
|
|
944
|
+
background: var(--accent);
|
|
945
|
+
color: #fff;
|
|
946
|
+
font-size: 14px;
|
|
947
|
+
font-weight: 600;
|
|
948
|
+
cursor: pointer;
|
|
949
|
+
transition: background 0.15s, transform 0.1s;
|
|
950
|
+
}
|
|
951
|
+
.mate-onboarding-btn:hover {
|
|
952
|
+
filter: brightness(1.08);
|
|
953
|
+
}
|
|
954
|
+
.mate-onboarding-btn:active {
|
|
955
|
+
transform: scale(0.98);
|
|
956
|
+
}
|
|
957
|
+
|
|
863
958
|
.mate-sidebar-avatar {
|
|
864
959
|
width: 28px;
|
|
865
960
|
height: 28px;
|
|
@@ -2143,20 +2238,32 @@ body.mate-dm-active .notes-archive-header button:hover {
|
|
|
2143
2238
|
object-fit: cover;
|
|
2144
2239
|
margin-top: 2px;
|
|
2145
2240
|
}
|
|
2146
|
-
body.mate-dm-active .dm-bubble-avatar
|
|
2241
|
+
body.mate-dm-active .dm-bubble-avatar,
|
|
2242
|
+
body.wide-view .dm-bubble-avatar {
|
|
2147
2243
|
display: block;
|
|
2148
2244
|
}
|
|
2149
2245
|
|
|
2150
2246
|
/* --- DM bubble header (name + time) --- */
|
|
2247
|
+
/* Content wrapper: full width by default so child % sizing works,
|
|
2248
|
+
becomes flex child in DM/wide modes */
|
|
2151
2249
|
.dm-bubble-content {
|
|
2152
|
-
|
|
2153
|
-
min-width: 0;
|
|
2250
|
+
width: 100%;
|
|
2154
2251
|
}
|
|
2155
2252
|
.dm-bubble-header {
|
|
2156
|
-
display:
|
|
2253
|
+
display: none;
|
|
2157
2254
|
align-items: baseline;
|
|
2158
2255
|
gap: 8px;
|
|
2159
2256
|
}
|
|
2257
|
+
body.mate-dm-active .dm-bubble-header,
|
|
2258
|
+
body.wide-view .dm-bubble-header {
|
|
2259
|
+
display: flex;
|
|
2260
|
+
}
|
|
2261
|
+
body.mate-dm-active .dm-bubble-content,
|
|
2262
|
+
body.wide-view .dm-bubble-content {
|
|
2263
|
+
width: auto;
|
|
2264
|
+
flex: 1;
|
|
2265
|
+
min-width: 0;
|
|
2266
|
+
}
|
|
2160
2267
|
.dm-bubble-name {
|
|
2161
2268
|
font-weight: 700;
|
|
2162
2269
|
font-size: 15px;
|
|
@@ -43,11 +43,36 @@
|
|
|
43
43
|
flex-shrink: 0;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
.mention-item-info {
|
|
47
|
+
flex: 1;
|
|
48
|
+
min-width: 0;
|
|
49
|
+
display: flex;
|
|
50
|
+
flex-direction: column;
|
|
51
|
+
gap: 1px;
|
|
52
|
+
}
|
|
46
53
|
.mention-item-name {
|
|
47
54
|
font-size: 14px;
|
|
48
55
|
font-weight: 600;
|
|
49
56
|
color: var(--text);
|
|
50
|
-
|
|
57
|
+
}
|
|
58
|
+
.mention-item-bio {
|
|
59
|
+
font-size: 12px;
|
|
60
|
+
color: var(--text-muted);
|
|
61
|
+
white-space: nowrap;
|
|
62
|
+
overflow: hidden;
|
|
63
|
+
text-overflow: ellipsis;
|
|
64
|
+
}
|
|
65
|
+
.mention-item-badge {
|
|
66
|
+
display: inline-block;
|
|
67
|
+
font-size: 9px;
|
|
68
|
+
font-weight: 800;
|
|
69
|
+
letter-spacing: 0.5px;
|
|
70
|
+
padding: 1px 5px;
|
|
71
|
+
border-radius: 3px;
|
|
72
|
+
background: var(--accent-12, rgba(255,184,108,0.12));
|
|
73
|
+
color: var(--accent, #ffb86c);
|
|
74
|
+
vertical-align: middle;
|
|
75
|
+
margin-left: 5px;
|
|
51
76
|
}
|
|
52
77
|
|
|
53
78
|
.mention-item-dot {
|