v3: added content slugs, fixed real-time updates in client, added @mentions across the app, added new file selector and drop zone

This commit is contained in:
khannurien
2026-03-22 16:06:26 +00:00
parent 39a0cc397e
commit 34e908d1bc
42 changed files with 2170 additions and 628 deletions

View File

@@ -1,6 +1,6 @@
/* ── Markdown prose ── */
.md p {
margin: 0 0 0.7em;
margin: 0 0 0.85em;
}
.md p:last-child {
margin-bottom: 0;
@@ -120,7 +120,7 @@
.dump-comment {
font-size: 1.05rem;
line-height: 1.6;
line-height: 1.72;
opacity: 0.85;
border-left: 3px solid var(--color-accent);
margin: 0;
@@ -318,6 +318,138 @@
opacity: 0.7;
}
/* ── FileDropZone ── */
.fdz-wrapper {
display: flex;
flex-direction: column;
gap: 0.4rem;
}
.fdz-label {
font-size: 0.9rem;
font-weight: 500;
}
.fdz {
border: 2px dashed var(--color-border-subtle);
border-radius: 10px;
background: var(--color-surface);
cursor: pointer;
transition: border-color 0.15s, background 0.15s;
outline: none;
}
.fdz:hover:not(.fdz--disabled):not(.fdz--filled),
.fdz:focus-visible {
border-color: var(--color-accent);
}
.fdz--drag {
border-color: var(--color-accent);
background: color-mix(in srgb, var(--color-accent) 8%, var(--color-surface));
}
.fdz--disabled {
cursor: not-allowed;
opacity: 0.55;
}
.fdz--filled {
cursor: default;
border-style: solid;
}
.fdz__empty {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.3rem;
padding: 2rem 1.5rem;
user-select: none;
}
.fdz__upload-icon {
width: 2rem;
height: 2rem;
opacity: 0.4;
margin-bottom: 0.2rem;
}
.fdz__hint {
margin: 0;
font-size: 0.9rem;
font-weight: 500;
}
.fdz__browse {
margin: 0;
font-size: 0.85rem;
color: var(--color-text-secondary);
}
.fdz__browse-link {
color: var(--color-accent);
text-decoration: underline;
text-underline-offset: 2px;
}
.fdz__limit {
margin: 0.25rem 0 0;
font-size: 0.78rem;
color: var(--color-text-muted);
}
.fdz__file {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.85rem 1rem;
}
.fdz__file-icon {
font-size: 1.5rem;
flex-shrink: 0;
}
.fdz__file-meta {
display: flex;
flex-direction: column;
gap: 0.15rem;
min-width: 0;
flex: 1;
}
.fdz__file-name {
font-size: 0.9rem;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.fdz__file-size {
font-size: 0.78rem;
color: var(--color-text-muted);
}
.fdz__clear {
flex-shrink: 0;
background: none;
border: none;
cursor: pointer;
color: var(--color-text-muted);
font-size: 0.8rem;
padding: 0.3rem 0.5rem;
border-radius: 4px;
transition: color 0.12s, background 0.12s;
line-height: 1;
}
.fdz__clear:hover {
color: var(--color-text);
background: var(--color-border-subtle);
}
/* ── Local file / URL preview (DumpCreate) ── */
.local-preview-image {
width: 100%;
@@ -559,7 +691,8 @@
.file-preview-pdf {
width: 100%;
min-height: 420px;
height: 80vh;
min-height: 600px;
border-radius: 8px;
border: 2px solid var(--color-border);
display: block;
@@ -1907,16 +2040,22 @@ body.has-player .fab-new {
.dump-card-meta {
display: flex;
align-items: center;
align-items: baseline;
gap: 0.5rem;
margin-top: 0.2rem;
}
.dump-card-date {
display: block;
margin-top: 0;
}
.dump-edited-label,
.playlist-edited-label {
font-size: 0.72rem;
opacity: 0.5;
font-style: italic;
}
.playlist-card-meta {
display: flex;
align-items: center;
@@ -2213,9 +2352,10 @@ body.has-player .fab-new {
}
.playlist-detail-description {
font-size: 1rem;
margin: 0 0 0.5rem;
opacity: 0.75;
line-height: 1.5;
line-height: 1.75;
}
.playlist-detail-meta {
@@ -2518,11 +2658,32 @@ body.has-player .fab-new {
.comment-time {
font-size: 0.75rem;
color: var(--color-text-muted);
text-decoration: none;
}
.comment-time:hover {
text-decoration: underline;
text-underline-offset: 2px;
}
@keyframes comment-highlight {
0% { background: color-mix(in srgb, var(--color-accent) 18%, transparent); }
100% { background: transparent; }
}
.comment-node--highlight {
border-radius: 6px;
animation: comment-highlight 2s ease-out forwards;
}
.comment-edited {
font-size: 0.72rem;
color: var(--color-text-muted);
opacity: 0.7;
font-style: italic;
}
.comment-body {
font-size: 0.9rem;
line-height: 1.6;
line-height: 1.65;
color: var(--color-text);
}
@@ -2582,6 +2743,20 @@ body.has-player .fab-new {
border: 1px solid var(--color-border-subtle);
}
.comment-top-form-inner {
display: flex;
gap: 0.75rem;
align-items: flex-start;
}
.comment-top-form-body {
flex: 1;
display: flex;
flex-direction: column;
gap: 0.5rem;
min-width: 0;
}
.comment-reply-textarea {
width: 100%;
box-sizing: border-box;
@@ -2592,8 +2767,9 @@ body.has-player .fab-new {
font-family: inherit;
font-size: 0.875rem;
color: var(--color-text);
resize: vertical;
min-height: 4.5rem;
resize: none;
overflow: hidden;
min-height: 2.4rem;
transition: border-color 0.15s, box-shadow 0.15s;
}
@@ -2866,15 +3042,12 @@ body.has-player .fab-new {
gap: 1rem;
}
.notification-item {
display: flex;
align-items: center;
gap: 0.875rem;
padding: 0.875rem 1rem;
background: var(--color-surface);
border-radius: 10px;
border: 1px solid var(--color-border-subtle);
border-left: 3px solid transparent;
transition: background 0.12s, border-color 0.12s;
overflow: hidden;
}
.notification-item:hover {
background: color-mix(
@@ -2883,6 +3056,15 @@ body.has-player .fab-new {
var(--color-text) 8%
);
}
.notification-item-link {
display: flex;
align-items: center;
gap: 0.875rem;
padding: 0.875rem 1rem;
text-decoration: none;
color: inherit;
width: 100%;
}
.notification-item--unread {
border-left-color: var(--color-accent);
background: color-mix(in srgb, var(--color-accent) 9%, var(--color-surface));
@@ -2945,15 +3127,6 @@ body.has-player .fab-new {
white-space: nowrap;
flex-shrink: 0;
}
.notif-link {
color: var(--color-text);
text-decoration: none;
font-weight: 600;
}
.notif-link:hover {
color: var(--color-accent);
text-decoration: underline;
}
.load-more-btn {
display: block;
margin: 1.5rem auto 0;
@@ -2974,3 +3147,64 @@ body.has-player .fab-new {
opacity: 0.5;
cursor: not-allowed;
}
/* ── Mention autocomplete ── */
.mention-textarea-wrap {
position: relative;
}
.mention-textarea-wrap textarea {
width: 100%;
box-sizing: border-box;
}
.mention-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
z-index: 200;
list-style: none;
margin: 2px 0 0;
padding: 4px 0;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 8px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
max-height: 220px;
overflow-y: auto;
}
.mention-dropdown-item {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
cursor: pointer;
transition: background 0.1s;
}
.mention-dropdown-item:hover,
.mention-dropdown-item--selected {
background: var(--color-bg);
}
.mention-dropdown-username {
font-size: 0.9rem;
color: var(--color-text);
}
.notif-icon--mention {
font-weight: 700;
font-family: monospace;
}
/* ── Tooltip ── */
.tooltip {
background: var(--color-surface);
color: var(--color-text);
border: 1px solid var(--color-border-subtle);
padding: 0.3em 0.65em;
border-radius: 5px;
font-size: 0.78rem;
font-style: normal;
white-space: nowrap;
pointer-events: none;
z-index: 9999;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}