diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index b556033d..4e631160 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -394,7 +394,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
{conversations?.loading && !isDeletingConversation && (
diff --git a/frontend/src/agents/AgentPreview.tsx b/frontend/src/agents/AgentPreview.tsx index 4d970bac..149bc83b 100644 --- a/frontend/src/agents/AgentPreview.tsx +++ b/frontend/src/agents/AgentPreview.tsx @@ -112,7 +112,7 @@ export default function AgentPreview() { }, [queries]); return (
-
+
{t('agents.title')} -

+

{t('agents.description')}

diff --git a/frontend/src/agents/NewAgent.tsx b/frontend/src/agents/NewAgent.tsx index ced4a28d..9b7d951e 100644 --- a/frontend/src/agents/NewAgent.tsx +++ b/frontend/src/agents/NewAgent.tsx @@ -744,7 +744,7 @@ export default function NewAgent({ mode }: { mode: 'new' | 'edit' | 'draft' }) {
-
+

{t('agents.form.sections.meta')} diff --git a/frontend/src/components/FilePicker.tsx b/frontend/src/components/FilePicker.tsx index 97e55510..e7c4b476 100644 --- a/frontend/src/components/FilePicker.tsx +++ b/frontend/src/components/FilePicker.tsx @@ -443,7 +443,7 @@ export const FilePicker: React.FC = ({ { diff --git a/frontend/src/components/MultiSelectPopup.tsx b/frontend/src/components/MultiSelectPopup.tsx index 7ccee569..2fbd307e 100644 --- a/frontend/src/components/MultiSelectPopup.tsx +++ b/frontend/src/components/MultiSelectPopup.tsx @@ -212,7 +212,7 @@ export default function MultiSelectPopup({

) : ( -
+
{filteredOptions.length === 0 ? (
-
+
{options ? ( <> {filteredOptions?.map((option: any, index: number) => { diff --git a/frontend/src/components/ToolsPopup.tsx b/frontend/src/components/ToolsPopup.tsx index 11f01cab..a74b50ba 100644 --- a/frontend/src/components/ToolsPopup.tsx +++ b/frontend/src/components/ToolsPopup.tsx @@ -175,7 +175,7 @@ export default function ToolsPopup({
) : (
-
+
{filteredTools.length === 0 ? (
{String(children).replace(/\n$/, '')} @@ -645,7 +644,7 @@ function AllSources(sources: AllSourcesProps) {

{`${sources.sources.length} ${t('conversation.sources.title')}`}

-
+
{sources.sources.map((source, index) => { const isExternalSource = source.link && source.link !== 'local'; return ( @@ -866,7 +865,6 @@ function Thought({ customStyle={{ margin: 0, borderRadius: 0, - scrollbarWidth: 'thin', }} > {String(children).replace(/\n$/, '')} diff --git a/frontend/src/index.css b/frontend/src/index.css index 9dfcc7f1..ce127aa4 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -110,7 +110,6 @@ layer(base); } @utility scrollbar-thin { - /* Thin scrollbar utility */ &::-webkit-scrollbar { width: 6px; height: 6px; @@ -122,31 +121,82 @@ layer(base); /* Light theme scrollbar */ &::-webkit-scrollbar-thumb { - background: rgba(215, 215, 215, 1); - border-radius: 3px; + background: #E2E8F0; + border-radius: 9999px; } &::-webkit-scrollbar-thumb:hover { - background: rgba(195, 195, 195, 1); + background: #8C9198; } /* Dark theme scrollbar */ .dark &::-webkit-scrollbar-thumb { - background: rgba(77, 78, 88, 1); - border-radius: 3px; + background: #949494; + border-radius: 9999px; } .dark &::-webkit-scrollbar-thumb:hover { - background: rgba(97, 98, 108, 1); + background: #F0F0F0; } - /* For Firefox - Light theme */ scrollbar-width: thin; - scrollbar-color: rgba(215, 215, 215, 1) transparent; + scrollbar-color: #E2E8F0 transparent; - /* For Firefox - Dark theme */ .dark & { - scrollbar-color: rgba(77, 78, 88, 1) transparent; + scrollbar-color: #949494 transparent; + } +} + +@utility scrollbar-overlay { + &::-webkit-scrollbar { + width: 6px; + height: 6px; + } + + &::-webkit-scrollbar-track { + background: transparent; + } + + &::-webkit-scrollbar-thumb { + background: transparent; + border-radius: 9999px; + } + + &:hover::-webkit-scrollbar-thumb { + background: #E2E8F0; + } + + &:hover::-webkit-scrollbar-thumb:hover { + background: #8C9198; + } + + .dark &::-webkit-scrollbar-thumb { + background: transparent; + border-radius: 9999px; + } + + .dark &:hover::-webkit-scrollbar-thumb { + background: #949494; + } + + .dark &:hover::-webkit-scrollbar-thumb:hover { + background: #F0F0F0; + } + + /* Standard scrollbar properties (Chrome 121+, Firefox) */ + scrollbar-width: thin; + scrollbar-color: transparent transparent; + + &:hover { + scrollbar-color: #E2E8F0 transparent; + } + + .dark & { + scrollbar-color: transparent transparent; + } + + .dark &:hover { + scrollbar-color: #949494 transparent; } } @@ -177,16 +227,25 @@ layer(base); min-width: 150px; max-width: 320px; overflow: auto; - scrollbar-width: thin; - scrollbar-color: grey transparent; } & td { min-width: 150px; max-width: 320px; overflow: auto; - scrollbar-width: thin; - scrollbar-color: grey transparent; + } + + @supports (-moz-appearance: none) { + & th, + & td { + scrollbar-width: thin; + scrollbar-color: #E2E8F0 transparent; + } + + .dark & th, + .dark & td { + scrollbar-color: #949494 transparent; + } } } @@ -206,23 +265,35 @@ layer(base); background-color: #202124; /* raisin-black */ } ::-webkit-scrollbar { - width: 8px; + width: 6px; + height: 6px; } ::-webkit-scrollbar-track { - background: #f1f1f1; - } - .dark ::-webkit-scrollbar-track { - background: #2f3036; + background: transparent; } ::-webkit-scrollbar-thumb { - background: #888; - border-radius: 40px; + background: #E2E8F0; + border-radius: 9999px; } ::-webkit-scrollbar-thumb:hover { - background: #555; + background: #8C9198; + } + .dark ::-webkit-scrollbar-thumb { + background: #949494; } .dark ::-webkit-scrollbar-thumb:hover { - background: #b1afaf; + background: #F0F0F0; + } + + /* Firefox: base scrollbar styles (Firefox ignores ::-webkit-scrollbar) */ + @supports (-moz-appearance: none) { + * { + scrollbar-width: thin; + scrollbar-color: #E2E8F0 transparent; + } + .dark * { + scrollbar-color: #949494 transparent; + } } } @@ -637,9 +708,6 @@ Avoid over-scrolling in mobile browsers src: url('/fonts/IBMPlexMono-Medium.ttf'); } - ::-webkit-scrollbar { - width: 10; - } /* Light mode specific autofill styles */ input:-webkit-autofill, input:-webkit-autofill:hover, diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 6146911d..8d6adfee 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -6,6 +6,66 @@ import { Provider } from 'react-redux'; import store from './store'; import './index.css'; +// Show scrollbar on scroll for scrollbar-overlay elements, hide after 1s idle +const scrollTimers = new WeakMap>(); +let sbIdCounter = 0; +const sbStyleEl = document.createElement('style'); +document.head.appendChild(sbStyleEl); +const activeSbs = new Map(); +function rebuildSbStyles() { + sbStyleEl.textContent = Array.from(activeSbs.values()).join(''); +} +function showOverlayScrollbar(el: HTMLElement) { + if (!el.dataset.sbId) el.dataset.sbId = String(++sbIdCounter); + const sbId = el.dataset.sbId; + const isDark = document.body.classList.contains('dark'); + const thumb = isDark ? '#949494' : '#E2E8F0'; + const thumbHover = isDark ? '#F0F0F0' : '#8C9198'; + // Webkit: inject