diff --git a/backend/internal/api/og.go b/backend/internal/api/og.go index f00e13c..09df0cd 100644 --- a/backend/internal/api/og.go +++ b/backend/internal/api/og.go @@ -875,11 +875,11 @@ func generateOGImagePNG(author, text, quote, source, avatarURL string) image.Ima height := 630 padding := 100 - bgPrimary := color.RGBA{12, 10, 20, 255} - accent := color.RGBA{168, 85, 247, 255} - textPrimary := color.RGBA{244, 240, 255, 255} - textSecondary := color.RGBA{168, 158, 200, 255} - border := color.RGBA{45, 38, 64, 255} + bgPrimary := color.RGBA{10, 10, 13, 255} + accent := color.RGBA{149, 122, 134, 255} + textPrimary := color.RGBA{234, 234, 238, 255} + textSecondary := color.RGBA{168, 164, 171, 255} + border := color.RGBA{42, 40, 46, 255} img := image.NewRGBA(image.Rect(0, 0, width, height)) @@ -1118,12 +1118,12 @@ func generateCollectionOGImagePNG(author, collectionName, description, icon, ava height := 630 padding := 120 - bgPrimary := color.RGBA{12, 10, 20, 255} - accent := color.RGBA{168, 85, 247, 255} - textPrimary := color.RGBA{244, 240, 255, 255} - textSecondary := color.RGBA{168, 158, 200, 255} - textTertiary := color.RGBA{107, 95, 138, 255} - border := color.RGBA{45, 38, 64, 255} + bgPrimary := color.RGBA{10, 10, 13, 255} + accent := color.RGBA{149, 122, 134, 255} + textPrimary := color.RGBA{234, 234, 238, 255} + textSecondary := color.RGBA{168, 164, 171, 255} + textTertiary := color.RGBA{107, 103, 112, 255} + border := color.RGBA{42, 40, 46, 255} img := image.NewRGBA(image.Rect(0, 0, width, height)) @@ -1220,11 +1220,11 @@ func generateHighlightOGImagePNG(author, pageTitle, quote, source, avatarURL str height := 630 padding := 100 - bgPrimary := color.RGBA{12, 10, 20, 255} - accent := color.RGBA{250, 204, 21, 255} - textPrimary := color.RGBA{244, 240, 255, 255} - textSecondary := color.RGBA{168, 158, 200, 255} - border := color.RGBA{45, 38, 64, 255} + bgPrimary := color.RGBA{10, 10, 13, 255} + accent := color.RGBA{149, 122, 134, 255} + textPrimary := color.RGBA{234, 234, 238, 255} + textSecondary := color.RGBA{168, 164, 171, 255} + border := color.RGBA{42, 40, 46, 255} img := image.NewRGBA(image.Rect(0, 0, width, height)) diff --git a/extension/background/service-worker.js b/extension/background/service-worker.js index 16a3bac..471f2c5 100644 --- a/extension/background/service-worker.js +++ b/extension/background/service-worker.js @@ -398,7 +398,7 @@ async function handleMessage(request, sender, sendResponse) { sendResponse({ success: true, data: allItems }); if (sender.tab) { - const count = items.length; + const count = allItems.length; chrome.action .setBadgeText({ text: count > 0 ? count.toString() : "", diff --git a/extension/content/content.css b/extension/content/content.css index eb984d8..ef62d1e 100644 --- a/extension/content/content.css +++ b/extension/content/content.css @@ -1,15 +1,15 @@ ::highlight(margin-highlight-preview) { - background-color: rgba(168, 85, 247, 0.3); + background-color: rgba(149, 122, 134, 0.3); color: inherit; } ::highlight(margin-scroll-highlight) { - background-color: rgba(99, 102, 241, 0.4); + background-color: rgba(149, 122, 134, 0.5); color: inherit; } ::highlight(margin-page-highlights) { - background-color: rgba(252, 211, 77, 0.3); + background-color: rgba(149, 122, 134, 0.25); color: inherit; } diff --git a/extension/content/content.js b/extension/content/content.js index 3f0056d..a899e77 100644 --- a/extension/content/content.js +++ b/extension/content/content.js @@ -9,35 +9,39 @@ const OVERLAY_STYLES = ` :host { all: initial; - --bg-primary: #09090b; - --bg-secondary: #0f0f12; - --bg-tertiary: #18181b; - --bg-card: #09090b; - --bg-elevated: #18181b; - --bg-hover: #27272a; + --bg-primary: #0a0a0d; + --bg-secondary: #121216; + --bg-tertiary: #1a1a1f; + --bg-card: #0f0f13; + --bg-elevated: #18181d; + --bg-hover: #1e1e24; - --text-primary: #e4e4e7; - --text-secondary: #a1a1aa; - --border: #27272a; + --text-primary: #eaeaee; + --text-secondary: #b7b6c5; + --text-tertiary: #6e6d7a; + --border: rgba(183, 182, 197, 0.12); - --accent: #6366f1; - --accent-hover: #4f46e5; + --accent: #957a86; + --accent-hover: #a98d98; + --accent-subtle: rgba(149, 122, 134, 0.15); } :host(.light) { - --bg-primary: #ffffff; - --bg-secondary: #f4f4f5; - --bg-tertiary: #e4e4e7; + --bg-primary: #f8f8fa; + --bg-secondary: #ffffff; + --bg-tertiary: #f0f0f4; --bg-card: #ffffff; - --bg-elevated: #f4f4f5; - --bg-hover: #e4e4e7; + --bg-elevated: #ffffff; + --bg-hover: #eeeef2; - --text-primary: #18181b; - --text-secondary: #52525b; - --border: #e4e4e7; + --text-primary: #18171c; + --text-secondary: #5c495a; + --text-tertiary: #8a8494; + --border: rgba(92, 73, 90, 0.12); - --accent: #4f46e5; - --accent-hover: #4338ca; + --accent: #7a5f6d; + --accent-hover: #664e5b; + --accent-subtle: rgba(149, 122, 134, 0.12); } .margin-overlay { @@ -51,78 +55,136 @@ .margin-popover { position: absolute; - width: 320px; + width: 300px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; padding: 0; - box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 10px 10px -5px rgba(0, 0, 0, 0.2); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); display: flex; flex-direction: column; pointer-events: auto; z-index: 2147483647; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + font-family: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, sans-serif; color: var(--text-primary); opacity: 0; - transform: scale(0.95); + transform: translateY(-4px); animation: popover-in 0.15s forwards; - max-height: 480px; + max-height: 400px; overflow: hidden; } - @keyframes popover-in { to { opacity: 1; transform: scale(1); } } + @keyframes popover-in { to { opacity: 1; transform: translateY(0); } } + .popover-header { - padding: 12px 16px; + padding: 10px 14px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; - background: var(--bg-secondary); + background: var(--bg-primary); border-radius: 12px 12px 0 0; - font-weight: 600; - font-size: 13px; - color: var(--text-primary); - } + font-weight: 500; + font-size: 11px; + color: var(--text-tertiary); + text-transform: uppercase; + letter-spacing: 0.5px; + } + .popover-close { + background: none; + border: none; + color: var(--text-tertiary); + cursor: pointer; + padding: 2px; + font-size: 16px; + line-height: 1; + opacity: 0.6; + transition: opacity 0.15s; + } + .popover-close:hover { opacity: 1; } + .popover-scroll-area { overflow-y: auto; - max-height: 400px; + max-height: 340px; } - .popover-item-block { + + .comment-item { + padding: 12px 14px; border-bottom: 1px solid var(--border); - margin-bottom: 0; - animation: fade-in 0.2s; } - .popover-item-block:last-child { + .comment-item:last-child { border-bottom: none; } - .popover-item-header { - padding: 12px 16px 4px; + + .comment-header { display: flex; align-items: center; gap: 8px; + margin-bottom: 6px; } - .popover-avatar { - width: 24px; height: 24px; border-radius: 50%; background: var(--bg-hover); - display: flex; align-items: center; justify-content: center; - font-size: 10px; color: var(--text-secondary); - } - .popover-handle { font-size: 12px; font-weight: 600; color: var(--text-primary); } - .popover-close { background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 4px; } - .popover-close:hover { color: var(--text-primary); } - .popover-content { padding: 4px 16px 12px; font-size: 13px; line-height: 1.5; color: var(--text-primary); } - .popover-quote { - margin-top: 8px; padding: 6px 10px; background: var(--bg-tertiary); - border-left: 2px solid var(--accent); border-radius: 4px; - font-size: 11px; color: var(--text-secondary); font-style: italic; - } - .popover-actions { - padding: 8px 16px; - display: flex; justify-content: flex-end; gap: 8px; + .comment-avatar { + width: 22px; + height: 22px; + border-radius: 50%; + background: var(--accent); + display: flex; + align-items: center; + justify-content: center; + font-size: 9px; + font-weight: 600; + color: white; + } + .comment-handle { + font-size: 12px; + font-weight: 600; + color: var(--text-primary); + } + .comment-time { + font-size: 11px; + color: var(--text-tertiary); + margin-left: auto; + } + + .comment-text { + font-size: 13px; + line-height: 1.5; + color: var(--text-primary); + margin-bottom: 8px; + } + + .highlight-only-badge { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 11px; + color: var(--text-tertiary); + font-style: italic; + } + + .comment-actions { + display: flex; + gap: 8px; + margin-top: 8px; + } + .highlight-only-badge { + font-size: 11px; + color: var(--text-tertiary); + font-style: italic; + opacity: 0.7; } - .btn-action { - background: none; border: 1px solid var(--border); border-radius: 4px; - padding: 4px 8px; color: var(--text-secondary); font-size: 11px; cursor: pointer; + .comment-action-btn { + background: none; + border: none; + padding: 4px 8px; + color: var(--text-tertiary); + font-size: 11px; + cursor: pointer; + border-radius: 4px; + transition: all 0.15s; + } + .comment-action-btn:hover { + background: var(--bg-hover); + color: var(--text-secondary); } - .btn-action:hover { background: var(--bg-hover); color: var(--text-primary); } .margin-selection-popup { position: fixed; @@ -132,10 +194,10 @@ background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; - box-shadow: 0 8px 16px rgba(0,0,0,0.4); + box-shadow: 0 8px 24px rgba(0,0,0,0.3); z-index: 2147483647; pointer-events: auto; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + font-family: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, sans-serif; animation: popover-in 0.15s forwards; } .selection-btn { @@ -168,10 +230,10 @@ border-radius: 12px; padding: 16px; box-sizing: border-box; - box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5); + box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4); z-index: 2147483647; pointer-events: auto; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + font-family: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, sans-serif; color: var(--text-primary); animation: popover-in 0.15s forwards; overflow: hidden; @@ -181,8 +243,8 @@ } .inline-compose-quote { padding: 8px 12px; - background: var(--bg-tertiary); - border-left: 3px solid var(--accent); + background: var(--accent-subtle); + border-left: 2px solid var(--accent); border-radius: 4px; font-size: 12px; color: var(--text-secondary); @@ -247,13 +309,13 @@ } .reply-section { border-top: 1px solid var(--border); - padding: 12px 16px; - background: var(--bg-secondary); + padding: 10px 14px; + background: var(--bg-primary); border-radius: 0 0 12px 12px; } .reply-textarea { width: 100%; - min-height: 60px; + min-height: 50px; padding: 8px 10px; background: var(--bg-elevated); border: 1px solid var(--border); @@ -887,7 +949,7 @@ .join(","); popoverEl.dataset.itemIds = ids; - const popWidth = 320; + const popWidth = 300; const screenWidth = window.innerWidth; let finalLeft = left; if (left + popWidth > screenWidth) finalLeft = screenWidth - popWidth - 20; @@ -895,20 +957,8 @@ popoverEl.style.top = `${top + 20}px`; popoverEl.style.left = `${finalLeft}px`; - const hasHighlights = items.some((item) => item.type === "Highlight"); - const hasAnnotations = items.some((item) => item.type !== "Highlight"); - let title; - if (items.length > 1) { - if (hasHighlights && hasAnnotations) { - title = `${items.length} Items`; - } else if (hasHighlights) { - title = `${items.length} Highlights`; - } else { - title = `${items.length} Annotations`; - } - } else { - title = items[0]?.type === "Highlight" ? "Highlight" : "Annotation"; - } + const count = items.length; + const title = count === 1 ? "1 Comment" : `${count} Comments`; let contentHtml = items .map((item) => { @@ -916,42 +966,32 @@ const handle = author.handle || "User"; const avatar = author.avatar; const text = item.body?.value || item.text || ""; - const quote = - item.target?.selector?.exact || item.selector?.exact || ""; const id = item.id || item.uri; + const isHighlight = item.type === "Highlight"; - let avatarHtml = `
${handle[0]?.toUpperCase() || "U"}
`; + let avatarHtml = `
${handle[0]?.toUpperCase() || "U"}
`; if (avatar) { - avatarHtml = ``; + avatarHtml = ``; } - const isHighlight = item.type === "Highlight"; - let bodyHtml = ""; - if (isHighlight) { - bodyHtml = `
"${quote}"
`; + if (isHighlight && !text) { + bodyHtml = `
Highlighted
`; } else { - bodyHtml = `
${text}
`; - if (quote) { - bodyHtml += `
"${quote}"
`; - } + bodyHtml = `
${text}
`; } return ` -
-
-
- ${avatarHtml} - @${handle} -
-
-
- ${bodyHtml} -
-
- ${!isHighlight ? `` : ""} - -
+
+
+ ${avatarHtml} + @${handle} +
+ ${bodyHtml} +
+ ${!isHighlight ? `` : ""} + +
`; }) @@ -992,9 +1032,8 @@ btn.addEventListener("click", async () => { const id = btn.getAttribute("data-id"); const text = btn.getAttribute("data-text"); - const quote = btn.getAttribute("data-quote"); const u = `https://margin.at/annotation/${encodeURIComponent(id)}`; - const shareText = `${text ? text + "\n" : ""}${quote ? `"${quote}"\n` : ""}${u}`; + const shareText = text ? `${text}\n${u}` : u; try { await navigator.clipboard.writeText(shareText); diff --git a/extension/popup/popup.css b/extension/popup/popup.css index a134584..d7d9685 100644 --- a/extension/popup/popup.css +++ b/extension/popup/popup.css @@ -1,105 +1,110 @@ +@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&display=swap"); + :root { - --bg-primary: #09090b; - --bg-secondary: #0f0f12; - --bg-tertiary: #18181b; - --bg-card: #09090b; - --bg-elevated: #18181b; - --bg-hover: #27272a; - - --text-primary: #e4e4e7; - --text-secondary: #a1a1aa; - --text-tertiary: #71717a; - --border: #27272a; - --border-hover: #3f3f46; - - --accent: #6366f1; - --accent-hover: #4f46e5; - --accent-subtle: rgba(99, 102, 241, 0.1); - --accent-text: #818cf8; - --success: #10b981; - --error: #ef4444; - --warning: #f59e0b; - - --radius-sm: 4px; - --radius-md: 6px; - --radius-lg: 8px; + --bg-primary: #0a0a0d; + --bg-secondary: #121216; + --bg-tertiary: #1a1a1f; + --bg-card: #0f0f13; + --bg-elevated: #18181d; + --bg-hover: #1e1e24; + + --text-primary: #eaeaee; + --text-secondary: #b7b6c5; + --text-tertiary: #6e6d7a; + + --border: rgba(183, 182, 197, 0.12); + --border-hover: rgba(183, 182, 197, 0.2); + + --accent: #957a86; + --accent-hover: #a98d98; + --accent-subtle: rgba(149, 122, 134, 0.15); + --accent-text: #c4a8b2; + + --success: #7fb069; + --error: #d97766; + --warning: #e8a54b; + + --radius-sm: 6px; + --radius-md: 8px; + --radius-lg: 12px; --radius-full: 9999px; - --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); - --shadow-md: - 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + + --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3); + --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4); } @media (prefers-color-scheme: light) { :root { - --bg-primary: #ffffff; - --bg-secondary: #f4f4f5; - --bg-tertiary: #e4e4e7; + --bg-primary: #f8f8fa; + --bg-secondary: #ffffff; + --bg-tertiary: #f0f0f4; --bg-card: #ffffff; - --bg-elevated: #f4f4f5; - --bg-hover: #e4e4e7; - - --text-primary: #18181b; - --text-secondary: #52525b; - --text-tertiary: #71717a; - --border: #e4e4e7; - --border-hover: #d4d4d8; - - --accent: #4f46e5; - --accent-hover: #4338ca; - --accent-text: #4f46e5; - --accent-subtle: rgba(79, 70, 229, 0.1); - - --success: #059669; - --error: #dc2626; - --warning: #d97706; + --bg-elevated: #ffffff; + --bg-hover: #eeeef2; + + --text-primary: #18171c; + --text-secondary: #5c495a; + --text-tertiary: #8a8494; + + --border: rgba(92, 73, 90, 0.12); + --border-hover: rgba(92, 73, 90, 0.22); + + --accent: #7a5f6d; + --accent-hover: #664e5b; + --accent-subtle: rgba(149, 122, 134, 0.12); + --accent-text: #5c495a; + + --shadow-sm: 0 1px 3px rgba(92, 73, 90, 0.06); + --shadow-md: 0 4px 12px rgba(92, 73, 90, 0.08); } } body.light { - --bg-primary: #ffffff; - --bg-secondary: #f4f4f5; - --bg-tertiary: #e4e4e7; + --bg-primary: #f8f8fa; + --bg-secondary: #ffffff; + --bg-tertiary: #f0f0f4; --bg-card: #ffffff; - --bg-elevated: #f4f4f5; - --bg-hover: #e4e4e7; + --bg-elevated: #ffffff; + --bg-hover: #eeeef2; - --text-primary: #18181b; - --text-secondary: #52525b; - --text-tertiary: #71717a; - --border: #e4e4e7; - --border-hover: #d4d4d8; + --text-primary: #18171c; + --text-secondary: #5c495a; + --text-tertiary: #8a8494; - --accent: #4f46e5; - --accent-hover: #4338ca; - --accent-text: #4f46e5; - --accent-subtle: rgba(79, 70, 229, 0.1); + --border: rgba(92, 73, 90, 0.12); + --border-hover: rgba(92, 73, 90, 0.22); - --success: #059669; - --error: #dc2626; - --warning: #d97706; + --accent: #7a5f6d; + --accent-hover: #664e5b; + --accent-subtle: rgba(149, 122, 134, 0.12); + --accent-text: #5c495a; + + --shadow-sm: 0 1px 3px rgba(92, 73, 90, 0.06); + --shadow-md: 0 4px 12px rgba(92, 73, 90, 0.08); } body.dark { - --bg-primary: #09090b; - --bg-secondary: #0f0f12; - --bg-tertiary: #18181b; - --bg-card: #09090b; - --bg-elevated: #18181b; - --bg-hover: #27272a; - - --text-primary: #e4e4e7; - --text-secondary: #a1a1aa; - --text-tertiary: #71717a; - --border: #27272a; - --border-hover: #3f3f46; - - --accent: #6366f1; - --accent-hover: #4f46e5; - --accent-subtle: rgba(99, 102, 241, 0.1); - --accent-text: #818cf8; - --success: #10b981; - --error: #ef4444; - --warning: #f59e0b; + --bg-primary: #0a0a0d; + --bg-secondary: #121216; + --bg-tertiary: #1a1a1f; + --bg-card: #0f0f13; + --bg-elevated: #18181d; + --bg-hover: #1e1e24; + + --text-primary: #eaeaee; + --text-secondary: #b7b6c5; + --text-tertiary: #6e6d7a; + + --border: rgba(183, 182, 197, 0.12); + --border-hover: rgba(183, 182, 197, 0.2); + + --accent: #957a86; + --accent-hover: #a98d98; + --accent-subtle: rgba(149, 122, 134, 0.15); + --accent-text: #c4a8b2; + + --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3); + --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4); } * { @@ -111,10 +116,15 @@ body.dark { body { width: 380px; height: 520px; - font-family: "Inter", sans-serif; + font-family: + "IBM Plex Sans", + -apple-system, + BlinkMacSystemFont, + sans-serif; color: var(--text-primary); background-color: var(--bg-primary); overflow: hidden; + -webkit-font-smoothing: antialiased; } .popup { @@ -129,8 +139,7 @@ body { display: flex; justify-content: space-between; align-items: center; - background: var(--bg-secondary); - z-index: 10; + background: var(--bg-primary); } .popup-brand { @@ -145,8 +154,9 @@ body { .popup-title { font-weight: 600; - font-size: 16px; + font-size: 15px; color: var(--text-primary); + letter-spacing: -0.02em; } .user-info { @@ -159,15 +169,15 @@ body { font-size: 12px; color: var(--text-secondary); background: var(--bg-tertiary); - padding: 4px 8px; - border-radius: var(--radius-sm); + padding: 4px 10px; + border-radius: var(--radius-full); } .tabs { display: flex; border-bottom: 1px solid var(--border); - background: var(--bg-tertiary); - padding: 4px; + background: var(--bg-primary); + padding: 4px 8px; gap: 4px; } @@ -178,21 +188,20 @@ body { border: none; font-size: 12px; font-weight: 500; - color: var(--text-secondary); + color: var(--text-tertiary); cursor: pointer; border-radius: var(--radius-sm); transition: all 0.15s; } .tab-btn:hover { - color: var(--text-primary); + color: var(--text-secondary); background: var(--bg-hover); } .tab-btn.active { color: var(--text-primary); - background: var(--bg-card); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + background: var(--bg-tertiary); } .tab-content { @@ -220,14 +229,14 @@ body { align-items: center; justify-content: center; height: 100%; - color: var(--text-secondary); + color: var(--text-tertiary); gap: 12px; } .spinner { - width: 24px; - height: 24px; - border: 3px solid var(--border); + width: 20px; + height: 20px; + border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 1s linear infinite; @@ -251,20 +260,20 @@ body { } .login-at-logo { - font-size: 4rem; - font-weight: 800; + font-size: 3.5rem; + font-weight: 700; color: var(--accent); line-height: 1; } .login-title { - font-size: 1.1rem; + font-size: 1rem; font-weight: 600; color: var(--text-primary); } .login-text { - font-size: 14px; + font-size: 13px; color: var(--text-secondary); line-height: 1.5; } @@ -272,13 +281,13 @@ body { .quick-actions { padding: 12px 16px; border-bottom: 1px solid var(--border); - background: var(--bg-secondary); + background: var(--bg-primary); } .create-form { padding: 16px; border-bottom: 1px solid var(--border); - background: var(--bg-secondary); + background: var(--bg-primary); } .form-header { @@ -289,9 +298,10 @@ body { } .form-title { - font-size: 13px; + font-size: 12px; font-weight: 600; color: var(--text-primary); + letter-spacing: -0.01em; } .current-url { @@ -312,11 +322,9 @@ body { font-size: 13px; resize: none; margin-bottom: 10px; - background: var(--bg-tertiary); + background: var(--bg-elevated); color: var(--text-primary); - transition: - border-color 0.15s, - box-shadow 0.15s; + transition: border-color 0.15s; } .annotation-input::placeholder { @@ -326,7 +334,6 @@ body { .annotation-input:focus { outline: none; border-color: var(--accent); - box-shadow: 0 0 0 3px var(--accent-subtle); } .form-actions { @@ -338,7 +345,7 @@ body { margin-bottom: 12px; padding: 10px 12px; background: var(--accent-subtle); - border: 1px solid var(--accent); + border-left: 2px solid var(--accent); border-radius: var(--radius-sm); } @@ -351,7 +358,7 @@ body { font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; - color: var(--accent); + color: var(--accent-text); } .quote-preview-clear { @@ -371,7 +378,7 @@ body { .quote-preview-text { font-size: 12px; font-style: italic; - color: var(--text-primary); + color: var(--text-secondary); line-height: 1.4; max-height: 60px; overflow: hidden; @@ -386,7 +393,7 @@ body { justify-content: space-between; align-items: center; padding: 14px 16px; - background: var(--bg-secondary); + background: var(--bg-primary); } .section-title { @@ -401,27 +408,25 @@ body { font-size: 11px; background: var(--bg-tertiary); padding: 3px 8px; - border-radius: 10px; + border-radius: var(--radius-full); color: var(--text-secondary); } .annotations { display: flex; flex-direction: column; - gap: 10px; - padding: 12px 16px; + gap: 1px; + background: var(--border); } .annotation-item { - border: 1px solid var(--border); - border-radius: var(--radius-md); - padding: 12px; - background: var(--bg-card); - transition: border-color 0.15s; + padding: 14px 16px; + background: var(--bg-primary); + transition: background 0.15s; } .annotation-item:hover { - border-color: var(--border-hover); + background: var(--bg-hover); } .annotation-item-header { @@ -432,15 +437,15 @@ body { } .annotation-item-avatar { - width: 28px; - height: 28px; + width: 26px; + height: 26px; border-radius: 50%; - background: linear-gradient(135deg, var(--accent), #c084fc); - color: white; + background: var(--accent); + color: var(--bg-primary); display: flex; align-items: center; justify-content: center; - font-size: 11px; + font-size: 10px; font-weight: 600; } @@ -462,23 +467,23 @@ body { .annotation-type-badge { font-size: 10px; padding: 3px 8px; - border-radius: var(--radius-sm); + border-radius: var(--radius-full); font-weight: 500; } .annotation-type-badge.highlight { - background: rgba(251, 191, 36, 0.2); - color: #fbbf24; + background: var(--accent-subtle); + color: var(--accent-text); } .annotation-item-quote { - padding: 10px 12px; - border-left: 3px solid #fbbf24; - margin-bottom: 10px; - font-size: 13px; + padding: 8px 12px; + border-left: 2px solid var(--accent); + margin-bottom: 8px; + font-size: 12px; color: var(--text-secondary); font-style: italic; - background: rgba(251, 191, 36, 0.1); + background: var(--accent-subtle); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; } @@ -489,22 +494,20 @@ body { } .bookmark-item { - border: 1px solid var(--border); - border-radius: var(--radius-md); - padding: 12px; - background: var(--bg-card); + padding: 14px 16px; + background: var(--bg-primary); text-decoration: none; color: inherit; display: block; - transition: border-color 0.15s; + transition: background 0.15s; } .bookmark-item:hover { - border-color: var(--accent); + background: var(--bg-hover); } .bookmark-title { - font-size: 14px; + font-size: 13px; font-weight: 500; margin-bottom: 4px; white-space: nowrap; @@ -534,7 +537,7 @@ body { .empty-icon { margin-bottom: 12px; color: var(--text-tertiary); - opacity: 0.5; + opacity: 0.4; } .empty-text { @@ -568,7 +571,6 @@ body { .btn-primary:hover { background: var(--accent-hover); - transform: translateY(-1px); } .btn-secondary { @@ -586,7 +588,7 @@ body { .btn-icon { background: none; border: none; - color: var(--text-secondary); + color: var(--text-tertiary); cursor: pointer; padding: 6px; border-radius: var(--radius-sm); @@ -599,19 +601,18 @@ body { .popup-link { font-size: 12px; - color: var(--text-secondary); + color: var(--text-tertiary); text-decoration: none; } .popup-link:hover { - color: var(--accent); - text-decoration: underline; + color: var(--accent-text); } .popup-footer { padding: 12px 16px; border-top: 1px solid var(--border); - background: var(--bg-secondary); + background: var(--bg-primary); } .settings-view { @@ -653,20 +654,20 @@ body { } ::-webkit-scrollbar { - width: 6px; + width: 8px; } ::-webkit-scrollbar-track { - background: var(--bg-secondary); + background: transparent; } ::-webkit-scrollbar-thumb { - background: var(--border); - border-radius: 3px; + background: var(--bg-hover); + border-radius: var(--radius-full); } ::-webkit-scrollbar-thumb:hover { - background: var(--border-hover); + background: var(--text-tertiary); } .collection-selector { @@ -695,7 +696,7 @@ body { align-items: center; gap: 12px; padding: 12px; - background: var(--bg-card); + background: var(--bg-primary); border: 1px solid var(--border); border-radius: var(--radius-md); color: var(--text-primary); @@ -711,7 +712,7 @@ body { } .collection-select-btn:disabled { - opacity: 0.7; + opacity: 0.6; cursor: not-allowed; } @@ -725,8 +726,8 @@ body { .toggle-switch { position: relative; display: inline-block; - width: 44px; - height: 24px; + width: 40px; + height: 22px; flex-shrink: 0; } @@ -743,19 +744,19 @@ body { left: 0; right: 0; bottom: 0; - background-color: var(--border); + background-color: var(--bg-tertiary); transition: 0.2s; - border-radius: 24px; + border-radius: 22px; } .toggle-slider:before { position: absolute; content: ""; - height: 18px; - width: 18px; + height: 16px; + width: 16px; left: 3px; bottom: 3px; - background-color: var(--text-secondary); + background-color: var(--text-tertiary); transition: 0.2s; border-radius: 50%; } @@ -765,14 +766,14 @@ body { } .toggle-switch input:checked + .toggle-slider:before { - transform: translateX(20px); + transform: translateX(18px); background-color: white; } .settings-input { width: 100%; padding: 10px 12px; - background: var(--bg-tertiary); + background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-md); color: var(--text-primary); @@ -783,10 +784,11 @@ body { outline: none; border-color: var(--accent); } + .theme-toggle-group { display: flex; background: var(--bg-tertiary); - padding: 4px; + padding: 3px; border-radius: var(--radius-md); gap: 2px; margin-top: 8px; @@ -797,7 +799,7 @@ body { padding: 6px; border: none; background: transparent; - color: var(--text-secondary); + color: var(--text-tertiary); font-size: 12px; font-weight: 500; border-radius: var(--radius-sm); @@ -806,12 +808,10 @@ body { } .theme-btn:hover { - color: var(--text-primary); - background: rgba(128, 128, 128, 0.1); + color: var(--text-secondary); } .theme-btn.active { - background: var(--bg-card); + background: var(--bg-primary); color: var(--text-primary); - box-shadow: var(--shadow-sm); } diff --git a/extension/sidepanel/sidepanel.css b/extension/sidepanel/sidepanel.css index 6c7c99f..2e45e68 100644 --- a/extension/sidepanel/sidepanel.css +++ b/extension/sidepanel/sidepanel.css @@ -1,111 +1,110 @@ +@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&display=swap"); + :root { - --bg-primary: #09090b; - --bg-secondary: #0f0f12; - --bg-tertiary: #18181b; - --bg-card: #09090b; - --bg-hover: #18181b; - --bg-elevated: #18181b; - - --text-primary: #e4e4e7; - --text-secondary: #a1a1aa; - --text-tertiary: #71717a; - - --accent: #6366f1; - --accent-hover: #4f46e5; - --accent-subtle: rgba(99, 102, 241, 0.1); - --accent-text: #818cf8; - - --border: #27272a; - --border-hover: #3f3f46; - - --success: #10b981; - --error: #ef4444; - --warning: #f59e0b; - - --radius-sm: 4px; - --radius-md: 6px; - --radius-lg: 8px; + --bg-primary: #0a0a0d; + --bg-secondary: #121216; + --bg-tertiary: #1a1a1f; + --bg-card: #0f0f13; + --bg-elevated: #18181d; + --bg-hover: #1e1e24; + + --text-primary: #eaeaee; + --text-secondary: #b7b6c5; + --text-tertiary: #6e6d7a; + + --border: rgba(183, 182, 197, 0.12); + --border-hover: rgba(183, 182, 197, 0.2); + + --accent: #957a86; + --accent-hover: #a98d98; + --accent-subtle: rgba(149, 122, 134, 0.15); + --accent-text: #c4a8b2; + + --success: #7fb069; + --error: #d97766; + --warning: #e8a54b; + + --radius-sm: 6px; + --radius-md: 8px; + --radius-lg: 12px; --radius-full: 9999px; - --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); - --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1); + --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3); + --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4); } @media (prefers-color-scheme: light) { :root { - --bg-primary: #ffffff; - --bg-secondary: #f4f4f5; - --bg-tertiary: #e4e4e7; + --bg-primary: #f8f8fa; + --bg-secondary: #ffffff; + --bg-tertiary: #f0f0f4; --bg-card: #ffffff; - --bg-hover: #e4e4e7; - --bg-elevated: #f4f4f5; + --bg-elevated: #ffffff; + --bg-hover: #eeeef2; - --text-primary: #18181b; - --text-secondary: #52525b; - --text-tertiary: #71717a; + --text-primary: #18171c; + --text-secondary: #5c495a; + --text-tertiary: #8a8494; - --accent: #4f46e5; - --accent-hover: #4338ca; - --accent-subtle: rgba(79, 70, 229, 0.1); - --accent-text: #4f46e5; + --border: rgba(92, 73, 90, 0.12); + --border-hover: rgba(92, 73, 90, 0.22); - --border: #e4e4e7; - --border-hover: #d4d4d8; + --accent: #7a5f6d; + --accent-hover: #664e5b; + --accent-subtle: rgba(149, 122, 134, 0.12); + --accent-text: #5c495a; - --success: #059669; - --error: #dc2626; - --warning: #d97706; + --shadow-sm: 0 1px 3px rgba(92, 73, 90, 0.06); + --shadow-md: 0 4px 12px rgba(92, 73, 90, 0.08); } } body.light { - --bg-primary: #ffffff; - --bg-secondary: #f4f4f5; - --bg-tertiary: #e4e4e7; + --bg-primary: #f8f8fa; + --bg-secondary: #ffffff; + --bg-tertiary: #f0f0f4; --bg-card: #ffffff; - --bg-hover: #e4e4e7; - --bg-elevated: #f4f4f5; + --bg-elevated: #ffffff; + --bg-hover: #eeeef2; - --text-primary: #18181b; - --text-secondary: #52525b; - --text-tertiary: #71717a; + --text-primary: #18171c; + --text-secondary: #5c495a; + --text-tertiary: #8a8494; - --accent: #4f46e5; - --accent-hover: #4338ca; - --accent-subtle: rgba(79, 70, 229, 0.1); - --accent-text: #4f46e5; + --border: rgba(92, 73, 90, 0.12); + --border-hover: rgba(92, 73, 90, 0.22); - --border: #e4e4e7; - --border-hover: #d4d4d8; + --accent: #7a5f6d; + --accent-hover: #664e5b; + --accent-subtle: rgba(149, 122, 134, 0.12); + --accent-text: #5c495a; - --success: #059669; - --error: #dc2626; - --warning: #d97706; + --shadow-sm: 0 1px 3px rgba(92, 73, 90, 0.06); + --shadow-md: 0 4px 12px rgba(92, 73, 90, 0.08); } body.dark { - --bg-primary: #09090b; - --bg-secondary: #0f0f12; - --bg-tertiary: #18181b; - --bg-card: #09090b; - --bg-hover: #18181b; - --bg-elevated: #18181b; + --bg-primary: #0a0a0d; + --bg-secondary: #121216; + --bg-tertiary: #1a1a1f; + --bg-card: #0f0f13; + --bg-elevated: #18181d; + --bg-hover: #1e1e24; - --text-primary: #e4e4e7; - --text-secondary: #a1a1aa; - --text-tertiary: #71717a; + --text-primary: #eaeaee; + --text-secondary: #b7b6c5; + --text-tertiary: #6e6d7a; - --accent: #6366f1; - --accent-hover: #4f46e5; - --accent-subtle: rgba(99, 102, 241, 0.1); - --accent-text: #818cf8; + --border: rgba(183, 182, 197, 0.12); + --border-hover: rgba(183, 182, 197, 0.2); - --border: #27272a; - --border-hover: #3f3f46; + --accent: #957a86; + --accent-hover: #a98d98; + --accent-subtle: rgba(149, 122, 134, 0.15); + --accent-text: #c4a8b2; - --success: #10b981; - --error: #ef4444; - --warning: #f59e0b; + --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3); + --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4); } * { @@ -116,10 +115,9 @@ body.dark { body { font-family: - "Inter", + "IBM Plex Sans", -apple-system, BlinkMacSystemFont, - "Segoe UI", sans-serif; background: var(--bg-primary); color: var(--text-primary); @@ -143,155 +141,6 @@ body { background: var(--bg-primary); } -.user-handle { - font-size: 12px; - color: var(--text-secondary); - background: var(--bg-tertiary); - padding: 4px 8px; - border-radius: var(--radius-sm); -} - -.current-page-info { - display: flex; - align-items: center; - gap: 8px; - padding: 10px 16px; - background: var(--bg-primary); - border-bottom: 1px solid var(--border); -} - -.tabs { - display: flex; - border-bottom: 1px solid var(--border); - background: var(--bg-primary); - padding: 4px; - gap: 4px; - margin: 0; -} - -.tab-btn { - flex: 1; - padding: 10px 8px; - background: transparent; - border: none; - font-size: 12px; - font-weight: 500; - color: var(--text-secondary); - cursor: pointer; - border-radius: var(--radius-sm); - transition: all 0.15s; -} - -.tab-btn:hover { - color: var(--text-primary); - background: var(--bg-hover); -} - -.tab-btn.active { - color: var(--text-primary); - background: var(--bg-tertiary); - box-shadow: none; -} - -.quick-actions { - display: flex; - gap: 8px; - padding: 12px 16px; - border-bottom: 1px solid var(--border); - background: var(--bg-primary); -} - -.create-form { - padding: 16px; - border-bottom: 1px solid var(--border); - background: var(--bg-primary); -} - -.section-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 14px 16px; - background: var(--bg-primary); - border-bottom: 1px solid var(--border); -} - -.annotation-item { - border: 1px solid var(--border); - border-radius: var(--radius-md); - padding: 12px; - background: var(--bg-primary); - transition: border-color 0.15s; -} - -.annotation-item:hover { - border-color: var(--border-hover); - background: var(--bg-hover); -} - -.sidebar-footer { - display: flex; - align-items: center; - justify-content: space-between; - padding: 12px 16px; - border-top: 1px solid var(--border); - background: var(--bg-primary); -} - -::-webkit-scrollbar { - width: 10px; - height: 10px; -} - -::-webkit-scrollbar-track { - background: transparent; -} - -::-webkit-scrollbar-thumb { - background: var(--border); - border-radius: 5px; - border: 2px solid var(--bg-primary); -} - -::-webkit-scrollbar-thumb:hover { - background: var(--border-hover); -} - -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: - "Inter", - -apple-system, - BlinkMacSystemFont, - "Segoe UI", - sans-serif; - background: var(--bg-primary); - color: var(--text-primary); - min-height: 100vh; - -webkit-font-smoothing: antialiased; -} - -.sidebar { - display: flex; - flex-direction: column; - height: 100vh; - background: var(--bg-primary); -} - -.sidebar-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 14px 16px; - border-bottom: 1px solid var(--border); - background: var(--bg-secondary); -} - .sidebar-brand { display: flex; align-items: center; @@ -304,8 +153,9 @@ body { .sidebar-title { font-weight: 600; - font-size: 16px; + font-size: 15px; color: var(--text-primary); + letter-spacing: -0.02em; } .user-info { @@ -318,8 +168,8 @@ body { font-size: 12px; color: var(--text-secondary); background: var(--bg-tertiary); - padding: 4px 8px; - border-radius: var(--radius-sm); + padding: 4px 10px; + border-radius: var(--radius-full); } .current-page-info { @@ -327,13 +177,13 @@ body { align-items: center; gap: 8px; padding: 10px 16px; - background: var(--bg-tertiary); + background: var(--bg-primary); border-bottom: 1px solid var(--border); } .page-url { font-size: 12px; - color: var(--text-secondary); + color: var(--text-tertiary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -352,14 +202,14 @@ body { align-items: center; justify-content: center; height: 100%; - color: var(--text-secondary); + color: var(--text-tertiary); gap: 12px; } .spinner { - width: 24px; - height: 24px; - border: 3px solid var(--border); + width: 20px; + height: 20px; + border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 1s linear infinite; @@ -383,20 +233,20 @@ body { } .login-at-logo { - font-size: 4rem; - font-weight: 800; + font-size: 3.5rem; + font-weight: 700; color: var(--accent); line-height: 1; } .login-title { - font-size: 1.1rem; + font-size: 1rem; font-weight: 600; color: var(--text-primary); } .login-text { - font-size: 14px; + font-size: 13px; color: var(--text-secondary); line-height: 1.5; } @@ -404,8 +254,8 @@ body { .tabs { display: flex; border-bottom: 1px solid var(--border); - background: var(--bg-tertiary); - padding: 4px; + background: var(--bg-primary); + padding: 4px 8px; gap: 4px; margin: 0; } @@ -417,21 +267,20 @@ body { border: none; font-size: 12px; font-weight: 500; - color: var(--text-secondary); + color: var(--text-tertiary); cursor: pointer; border-radius: var(--radius-sm); transition: all 0.15s; } .tab-btn:hover { - color: var(--text-primary); + color: var(--text-secondary); background: var(--bg-hover); } .tab-btn.active { color: var(--text-primary); - background: var(--bg-card); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + background: var(--bg-tertiary); } .tab-content { @@ -450,7 +299,7 @@ body { gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--border); - background: var(--bg-secondary); + background: var(--bg-primary); } .btn { @@ -479,13 +328,11 @@ body { .btn-primary:hover { background: var(--accent-hover); - transform: translateY(-1px); } .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; - transform: none; } .btn-secondary { @@ -507,7 +354,7 @@ body { .btn-icon { background: none; border: none; - color: var(--text-secondary); + color: var(--text-tertiary); cursor: pointer; padding: 6px; border-radius: var(--radius-sm); @@ -521,7 +368,7 @@ body { .create-form { padding: 16px; border-bottom: 1px solid var(--border); - background: var(--bg-secondary); + background: var(--bg-primary); } .form-header { @@ -532,9 +379,10 @@ body { } .form-title { - font-size: 13px; + font-size: 12px; font-weight: 600; color: var(--text-primary); + letter-spacing: -0.01em; } .annotation-input { @@ -546,11 +394,9 @@ body { font-size: 13px; resize: none; margin-bottom: 10px; - background: var(--bg-tertiary); + background: var(--bg-elevated); color: var(--text-primary); - transition: - border-color 0.15s, - box-shadow 0.15s; + transition: border-color 0.15s; } .annotation-input::placeholder { @@ -560,7 +406,6 @@ body { .annotation-input:focus { outline: none; border-color: var(--accent); - box-shadow: 0 0 0 3px var(--accent-subtle); } .form-actions { @@ -572,8 +417,8 @@ body { margin-bottom: 12px; padding: 12px; background: var(--accent-subtle); - border: 1px solid var(--accent); - border-radius: var(--radius-md); + border-left: 2px solid var(--accent); + border-radius: var(--radius-sm); } .quote-preview-header { @@ -581,11 +426,11 @@ body { justify-content: space-between; align-items: center; margin-bottom: 8px; - font-size: 11px; + font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; - color: var(--accent); + color: var(--accent-text); } .quote-preview-clear { @@ -603,9 +448,9 @@ body { } .quote-preview-text { - font-size: 13px; + font-size: 12px; font-style: italic; - color: var(--text-primary); + color: var(--text-secondary); line-height: 1.5; } @@ -618,7 +463,8 @@ body { justify-content: space-between; align-items: center; padding: 14px 16px; - background: var(--bg-secondary); + background: var(--bg-primary); + border-bottom: 1px solid var(--border); } .section-title { @@ -633,27 +479,25 @@ body { font-size: 11px; background: var(--bg-tertiary); padding: 3px 8px; - border-radius: 10px; + border-radius: var(--radius-full); color: var(--text-secondary); } .annotations-list { display: flex; flex-direction: column; - gap: 10px; - padding: 12px 16px; + gap: 1px; + background: var(--border); } .annotation-item { - border: 1px solid var(--border); - border-radius: var(--radius-md); - padding: 12px; - background: var(--bg-card); - transition: border-color 0.15s; + padding: 14px 16px; + background: var(--bg-primary); + transition: background 0.15s; } .annotation-item:hover { - border-color: var(--border-hover); + background: var(--bg-hover); } .annotation-item-header { @@ -664,15 +508,15 @@ body { } .annotation-item-avatar { - width: 28px; - height: 28px; + width: 26px; + height: 26px; border-radius: 50%; - background: linear-gradient(135deg, var(--accent), #c084fc); - color: white; + background: var(--accent); + color: var(--bg-primary); display: flex; align-items: center; justify-content: center; - font-size: 11px; + font-size: 10px; font-weight: 600; } @@ -694,23 +538,23 @@ body { .annotation-type-badge { font-size: 10px; padding: 3px 8px; - border-radius: var(--radius-sm); + border-radius: var(--radius-full); font-weight: 500; } .annotation-type-badge.highlight { - background: rgba(251, 191, 36, 0.2); - color: #fbbf24; + background: var(--accent-subtle); + color: var(--accent-text); } .annotation-item-quote { - padding: 10px 12px; - border-left: 3px solid #fbbf24; - margin-bottom: 10px; - font-size: 13px; + padding: 8px 12px; + border-left: 2px solid var(--accent); + margin-bottom: 8px; + font-size: 12px; color: var(--text-secondary); font-style: italic; - background: rgba(251, 191, 36, 0.1); + background: var(--accent-subtle); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; } @@ -723,27 +567,25 @@ body { .bookmarks-list { display: flex; flex-direction: column; - gap: 10px; - padding: 12px 16px; + gap: 1px; + background: var(--border); } .bookmark-item { - border: 1px solid var(--border); - border-radius: var(--radius-md); - padding: 12px; - background: var(--bg-card); + padding: 14px 16px; + background: var(--bg-primary); text-decoration: none; color: inherit; display: block; - transition: border-color 0.15s; + transition: background 0.15s; } .bookmark-item:hover { - border-color: var(--accent); + background: var(--bg-hover); } .bookmark-title { - font-size: 14px; + font-size: 13px; font-weight: 500; margin-bottom: 4px; white-space: nowrap; @@ -773,7 +615,7 @@ body { .empty-icon { margin-bottom: 12px; color: var(--text-tertiary); - opacity: 0.5; + opacity: 0.4; } .empty-text { @@ -793,18 +635,17 @@ body { justify-content: space-between; padding: 12px 16px; border-top: 1px solid var(--border); - background: var(--bg-secondary); + background: var(--bg-primary); } .sidebar-link { font-size: 12px; - color: var(--text-secondary); + color: var(--text-tertiary); text-decoration: none; } .sidebar-link:hover { - color: var(--accent); - text-decoration: underline; + color: var(--accent-text); } .settings-view { @@ -852,17 +693,14 @@ body { border-radius: var(--radius-md); font-family: inherit; font-size: 13px; - background: var(--bg-tertiary); + background: var(--bg-elevated); color: var(--text-primary); - transition: - border-color 0.15s, - box-shadow 0.15s; + transition: border-color 0.15s; } .settings-input:focus { outline: none; border-color: var(--accent); - box-shadow: 0 0 0 3px var(--accent-subtle); } .setting-help { @@ -877,7 +715,7 @@ body { gap: 4px; padding: 6px 10px; font-size: 11px; - color: var(--accent); + color: var(--accent-text); background: var(--accent-subtle); border: none; border-radius: var(--radius-sm); @@ -887,24 +725,24 @@ body { } .scroll-to-btn:hover { - background: rgba(168, 85, 247, 0.25); + background: rgba(149, 122, 134, 0.25); } ::-webkit-scrollbar { - width: 6px; + width: 8px; } ::-webkit-scrollbar-track { - background: var(--bg-secondary); + background: transparent; } ::-webkit-scrollbar-thumb { - background: var(--border); - border-radius: 3px; + background: var(--bg-hover); + border-radius: var(--radius-full); } ::-webkit-scrollbar-thumb:hover { - background: var(--border-hover); + background: var(--text-tertiary); } .collection-selector { @@ -933,7 +771,7 @@ body { align-items: center; gap: 12px; padding: 12px; - background: var(--bg-card); + background: var(--bg-primary); border: 1px solid var(--border); border-radius: var(--radius-md); color: var(--text-primary); @@ -949,7 +787,7 @@ body { } .collection-select-btn:disabled { - opacity: 0.7; + opacity: 0.6; cursor: not-allowed; } @@ -963,8 +801,8 @@ body { .toggle-switch { position: relative; display: inline-block; - width: 44px; - height: 24px; + width: 40px; + height: 22px; flex-shrink: 0; } @@ -981,19 +819,19 @@ body { left: 0; right: 0; bottom: 0; - background-color: var(--border); + background-color: var(--bg-tertiary); transition: 0.2s; - border-radius: 24px; + border-radius: 22px; } .toggle-slider:before { position: absolute; content: ""; - height: 18px; - width: 18px; + height: 16px; + width: 16px; left: 3px; bottom: 3px; - background-color: var(--text-secondary); + background-color: var(--text-tertiary); transition: 0.2s; border-radius: 50%; } @@ -1003,13 +841,14 @@ body { } .toggle-switch input:checked + .toggle-slider:before { - transform: translateX(20px); + transform: translateX(18px); background-color: white; } + .theme-toggle-group { display: flex; background: var(--bg-tertiary); - padding: 4px; + padding: 3px; border-radius: var(--radius-md); gap: 2px; margin-top: 8px; @@ -1020,7 +859,7 @@ body { padding: 6px; border: none; background: transparent; - color: var(--text-secondary); + color: var(--text-tertiary); font-size: 12px; font-weight: 500; border-radius: var(--radius-sm); @@ -1029,12 +868,10 @@ body { } .theme-btn:hover { - color: var(--text-primary); - background: rgba(128, 128, 128, 0.1); + color: var(--text-secondary); } .theme-btn.active { - background: var(--bg-card); + background: var(--bg-primary); color: var(--text-primary); - box-shadow: var(--shadow-sm); } diff --git a/web/index.html b/web/index.html index c405979..5ef98e7 100644 --- a/web/index.html +++ b/web/index.html @@ -1,24 +1,22 @@ - - - - - - Margin - Write in the margins of the web - - - - - -
- - - + + + + + + Margin - Write in the margins of the web + + + + + + +
+ + + + \ No newline at end of file diff --git a/web/src/App.jsx b/web/src/App.jsx index 978323b..54a0727 100644 --- a/web/src/App.jsx +++ b/web/src/App.jsx @@ -1,8 +1,7 @@ import { Routes, Route } from "react-router-dom"; import { useEffect } from "react"; import { AuthProvider, useAuth } from "./context/AuthContext"; -import Sidebar from "./components/Sidebar"; -import RightSidebar from "./components/RightSidebar"; +import TopNav from "./components/TopNav"; import MobileNav from "./components/MobileNav"; import Feed from "./pages/Feed"; import Url from "./pages/Url"; @@ -31,49 +30,46 @@ function AppContent() { }, [user]); return ( -
+
- -
-
- - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } - /> - } - /> - } - /> - } - /> - } /> - } /> - } /> - } /> - -
-
- + +
+ + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } + /> + } + /> + } + /> + } + /> + } /> + } /> + } /> + } /> + +
); diff --git a/web/src/components/AnnotationCard.jsx b/web/src/components/AnnotationCard.jsx index ad88be9..6300be1 100644 --- a/web/src/components/AnnotationCard.jsx +++ b/web/src/components/AnnotationCard.jsx @@ -34,7 +34,6 @@ function buildTextFragmentUrl(baseUrl, selector) { if (!selector || selector.type !== "TextQuoteSelector" || !selector.exact) { return baseUrl; } - let fragment = ":~:text="; if (selector.prefix) { fragment += encodeURIComponent(selector.prefix) + "-,"; @@ -43,11 +42,10 @@ function buildTextFragmentUrl(baseUrl, selector) { if (selector.suffix) { fragment += ",-" + encodeURIComponent(selector.suffix); } - return baseUrl + "#" + fragment; } -const truncateUrl = (url, maxLength = 60) => { +const truncateUrl = (url, maxLength = 50) => { if (!url) return ""; try { const parsed = new URL(url); @@ -60,6 +58,15 @@ const truncateUrl = (url, maxLength = 60) => { } }; +function SembleBadge() { + return ( +
+ via Semble + Semble +
+ ); +} + export default function AnnotationCard({ annotation, onDelete, @@ -75,29 +82,28 @@ export default function AnnotationCard({ const [editText, setEditText] = useState(data.text || ""); const [editTags, setEditTags] = useState(data.tags?.join(", ") || ""); const [saving, setSaving] = useState(false); - const [showHistory, setShowHistory] = useState(false); const [editHistory, setEditHistory] = useState([]); const [loadingHistory, setLoadingHistory] = useState(false); - const [replies, setReplies] = useState([]); const [replyCount, setReplyCount] = useState(data.replyCount || 0); const [showReplies, setShowReplies] = useState(false); const [replyingTo, setReplyingTo] = useState(null); const [replyText, setReplyText] = useState(""); const [posting, setPosting] = useState(false); + const [hasEditHistory, setHasEditHistory] = useState(false); const isOwner = user?.did && data.author?.did === user.did; - - const [hasEditHistory, setHasEditHistory] = useState(false); + const isSemble = data.uri?.includes("network.cosmik"); + const highlightedText = + data.selector?.type === "TextQuoteSelector" ? data.selector.exact : null; + const fragmentUrl = buildTextFragmentUrl(data.url, data.selector); useEffect(() => { if (data.uri && !data.color && !data.description) { getEditHistory(data.uri) .then((history) => { - if (history && history.length > 0) { - setHasEditHistory(true); - } + if (history?.length > 0) setHasEditHistory(true); }) .catch(() => {}); } @@ -122,7 +128,6 @@ export default function AnnotationCard({ const handlePostReply = async (parentReply) => { if (!replyText.trim()) return; - try { setPosting(true); const parentUri = parentReply @@ -175,10 +180,6 @@ export default function AnnotationCard({ } }; - const highlightedText = - data.selector?.type === "TextQuoteSelector" ? data.selector.exact : null; - const fragmentUrl = buildTextFragmentUrl(data.url, data.selector); - const handleLike = async () => { if (!user) { login(); @@ -195,10 +196,9 @@ export default function AnnotationCard({ const cid = annotation.cid || data.cid || ""; if (data.uri && cid) await likeAnnotation(data.uri, cid); } - } catch (err) { + } catch { setIsLiked(!isLiked); setLikeCount((prev) => (isLiked ? prev + 1 : prev - 1)); - console.error("Failed to toggle like:", err); } }; @@ -218,6 +218,26 @@ export default function AnnotationCard({ } }; + const loadReplies = async () => { + if (!showReplies && replies.length === 0) { + try { + const res = await getReplies(data.uri); + if (res.items) setReplies(res.items); + } catch (err) { + console.error("Failed to load replies:", err); + } + } + setShowReplies(!showReplies); + }; + + const handleCollect = () => { + if (!user) { + login(); + return; + } + if (onAddToCollection) onAddToCollection(); + }; + return (
@@ -225,59 +245,37 @@ export default function AnnotationCard({
-
- {data.uri && data.uri.includes("network.cosmik") && ( -
- via Semble - Semble -
- )} - {hasEditHistory && !data.color && !data.description && ( - - )} - - {isOwner && !(data.uri && data.uri.includes("network.cosmik")) && ( - <> - {!data.color && !data.description && ( - - )} + {isSemble && } + {hasEditHistory && !data.color && !data.description && ( + + )} + {isOwner && !isSemble && ( + <> + {!data.color && !data.description && ( - - )} -
+ )} + + + )}
@@ -286,9 +284,8 @@ export default function AnnotationCard({

Edit History

@@ -321,7 +318,7 @@ export default function AnnotationCard({ > {truncateUrl(data.url)} {data.title && ( - • {data.title} + · {data.title} )} @@ -331,22 +328,20 @@ export default function AnnotationCard({ target="_blank" rel="noopener noreferrer" className="annotation-highlight" - style={{ - borderLeftColor: data.color || "var(--accent)", - }} + style={{ borderLeftColor: data.color || "var(--accent)" }} > - "{highlightedText}" + “{highlightedText}” )} {isEditing ? ( -
+