Files
claudecodeui/src/index.css
Eric Blanquer 3950c0e47f feat: add full-text search across conversations (#482)
* feat: add full-text search across conversations in sidebar

Add a search mode toggle (Projects/Conversations) to the sidebar search bar.
In Conversations mode, search text content across all JSONL session files
with debounced API calls, highlighted snippets, and click-to-navigate results.

* fix: address PR review feedback - session summary tracking, search sequence invalidation, fallback navigation, SSE streaming

- Track session summaries per-session in a Map instead of file-scoped variable
- Increment searchSeqRef when clearing conversation search to invalidate in-flight requests
- Add fallback session navigation when session not loaded in sidebar paging
- Stream search results via SSE for progressive display with progress indicator

* feat(search): add Codex/Gemini search and scroll-to-message navigation

- Search now includes Codex sessions (JSONL from ~/.codex/sessions/) and
  Gemini sessions (in-memory via sessionManager) in addition to Claude
- Search results include provider info and display a provider badge
- Click handler resolves the correct provider instead of hardcoding claude
- Clicking a search result loads all messages and scrolls to the matched
  message with a highlight flash animation

* fix(search): Codex search path matching and scroll reliability

- Fix Codex search scanning all sessions for every project by checking
  session_meta cwd match BEFORE scanning messages (was inflating match
  count and hitting limit before reaching later projects)
- Fix Codex search missing user messages in response_item entries
  (role=user with input_text content parts)
- Fix scroll-to-message being overridden by initial scrollToBottom
  using searchScrollActiveRef to inhibit competing scroll effects
- Fix snippet matching using contiguous substring instead of
  filtered words (which created non-existent phrases)

* feat(search): add Gemini CLI session support for search and history viewing

Gemini CLI sessions stored in ~/.gemini/tmp/<project>/chats/*.json are now
indexed for conversation search and can be loaded for viewing. Previously
only sessions created through the UI (sessionManager) were searchable.

* fix(search): full-word matching and longer highlight flash

- Search now uses word boundaries (\b) instead of substring matching,
  so "hi" no longer matches "this"
- Highlight flash extended to 4s with thicker outline and subtle
  background tint for better visibility
2026-03-06 16:59:23 +03:00

927 lines
25 KiB
CSS

@tailwind base;
@tailwind components;
@tailwind utilities;
/* Global spinner animation - defined early to ensure it loads */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 221.2 83.2% 53.3%;
--radius: 0.5rem;
/* Nav design tokens */
--nav-glass-bg: 0 0% 100% / 0.7;
--nav-glass-blur: 20px;
--nav-glass-saturate: 1.8;
--nav-tab-glow: 221.2 83.2% 53.3% / 0.18;
--nav-tab-ring: 221.2 83.2% 53.3% / 0.10;
--nav-float-shadow: 0 0% 0% / 0.06;
--nav-float-ring: 214.3 31.8% 91.4% / 0.5;
--nav-divider-color: 214.3 31.8% 91.4% / 0.5;
--nav-input-bg: 210 40% 96.1% / 0.5;
--nav-input-focus-ring: 221.2 83.2% 53.3% / 0.22;
/* Safe area CSS variables */
--safe-area-inset-top: env(safe-area-inset-top);
--safe-area-inset-right: env(safe-area-inset-right);
--safe-area-inset-bottom: env(safe-area-inset-bottom);
--safe-area-inset-left: env(safe-area-inset-left);
/* Mobile navigation dimensions - Single source of truth */
/* Floating nav: ~52px bar + 8px bottom margin + 12px px-3 top spacing */
--mobile-nav-height: 52px;
--mobile-nav-padding: 20px;
--mobile-nav-total: calc(var(--mobile-nav-height) + var(--mobile-nav-padding) + env(safe-area-inset-bottom, 0px));
/* Header safe area dimensions */
--header-safe-area-top: env(safe-area-inset-top, 0px);
--header-base-padding: 8px;
--header-total-padding: calc(var(--header-safe-area-top) + var(--header-base-padding));
}
/* Fallback for older iOS versions */
@supports (padding-top: constant(safe-area-inset-top)) {
:root {
--safe-area-inset-top: constant(safe-area-inset-top);
--safe-area-inset-right: constant(safe-area-inset-right);
--safe-area-inset-bottom: constant(safe-area-inset-bottom);
--safe-area-inset-left: constant(safe-area-inset-left);
}
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 217.2 91.2% 8%;
--card-foreground: 210 40% 98%;
--popover: 217.2 91.2% 8%;
--popover-foreground: 210 40% 98%;
--primary: 217.2 91.2% 59.8%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 220 13% 46%;
--ring: 217.2 91.2% 59.8%;
/* Nav design tokens — dark overrides */
--nav-glass-bg: 217.2 91.2% 8% / 0.55;
--nav-glass-blur: 24px;
--nav-glass-saturate: 1.6;
--nav-tab-glow: 217.2 91.2% 59.8% / 0.25;
--nav-tab-ring: 217.2 91.2% 59.8% / 0.15;
--nav-float-shadow: 0 0% 0% / 0.35;
--nav-float-ring: 217.2 32.6% 17.5% / 0.3;
--nav-divider-color: 217.2 32.6% 17.5% / 0.5;
--nav-input-bg: 217.2 32.6% 17.5% / 0.5;
--nav-input-focus-ring: 217.2 91.2% 59.8% / 0.25;
}
}
@layer base {
* {
@apply border-border;
box-sizing: border-box;
transition: none;
}
body {
@apply bg-background text-foreground;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
/* Root element with safe area padding for PWA */
#root {
min-height: 100vh;
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Apply safe area padding in standalone mode */
@supports (padding-top: env(safe-area-inset-top)) {
@media (display-mode: standalone) {
#root {
padding-top: var(--safe-area-inset-top);
padding-left: var(--safe-area-inset-left);
padding-right: var(--safe-area-inset-right);
}
}
}
/* PWA mode detected by JavaScript - more reliable */
body.pwa-mode #root {
padding-left: var(--safe-area-inset-left);
padding-right: var(--safe-area-inset-right);
height: 100vh;
overflow: hidden;
}
/* Adjust fixed inset positioning in PWA mode */
body.pwa-mode .fixed.inset-0 {
top: var(--header-total-padding);
left: var(--safe-area-inset-left);
right: var(--safe-area-inset-right);
bottom: 0;
}
/* Global transition defaults */
button,
a,
input,
textarea,
select,
[role="button"],
.transition-all {
transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* Color transitions for theme switching - exclude interactive elements */
body, div, section, article, aside, header, footer, nav, main,
h1, h2, h3, h4, h5, h6, p, span, blockquote,
ul, ol, li, dl, dt, dd,
table, thead, tbody, tfoot, tr, td, th,
form, fieldset, legend, label {
transition: background-color 200ms ease-in-out,
border-color 200ms ease-in-out,
color 200ms ease-in-out;
}
/* Transform transitions */
.transition-transform {
transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* Opacity transitions */
.transition-opacity {
transition: opacity 200ms ease-in-out;
}
/* Scale transitions for interactions */
.transition-scale {
transition: transform 100ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* Shadow transitions */
.transition-shadow {
transition: box-shadow 200ms ease-in-out;
}
/* Respect reduced motion preference */
@media (prefers-reduced-motion: reduce) {
*,
::before,
::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
}
@layer utilities {
/* Smooth hover transitions for interactive elements */
button:hover,
a:hover,
[role="button"]:hover {
transition-duration: 100ms;
}
/* Active state transitions */
button:active,
a:active,
[role="button"]:active {
transition-duration: 50ms;
}
/* Focus transitions */
button:focus-visible,
a:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
transition: outline-offset 150ms ease-out, box-shadow 150ms ease-out;
}
/* Sidebar transitions */
.sidebar-transition {
transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1),
opacity 300ms ease-in-out;
}
/* Nav glass surface — uses theme tokens */
.nav-glass {
background: hsl(var(--nav-glass-bg));
backdrop-filter: blur(var(--nav-glass-blur)) saturate(var(--nav-glass-saturate));
-webkit-backdrop-filter: blur(var(--nav-glass-blur)) saturate(var(--nav-glass-saturate));
}
/* Nav tab active pill glow — uses theme tokens */
.nav-tab-active {
box-shadow: 0 1px 8px hsl(var(--nav-tab-glow)),
0 0 0 1px hsl(var(--nav-tab-ring));
}
/* Floating mobile nav bar — uses theme tokens */
.mobile-nav-float {
box-shadow: 0 -1px 20px hsl(var(--nav-float-shadow)),
0 0 0 1px hsl(var(--nav-float-ring));
}
/* Subtle sidebar divider — uses theme tokens */
.nav-divider {
height: 1px;
background: linear-gradient(90deg, transparent, hsl(var(--nav-divider-color)) 20%, hsl(var(--nav-divider-color)) 80%, transparent);
}
/* Nav search input surface — uses theme tokens */
.nav-search-input {
background: hsl(var(--nav-input-bg));
border: none;
}
.nav-search-input:focus-within {
background: hsl(var(--background));
box-shadow: 0 0 0 2px hsl(var(--nav-input-focus-ring));
}
/* Modal and dropdown transitions */
.modal-transition {
transition: opacity 200ms ease-in-out,
transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* Chat message transitions */
.message-transition {
transition: opacity 300ms ease-in-out,
transform 300ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* Height transitions for expanding elements */
.height-transition {
transition: height 200ms ease-in-out,
max-height 200ms ease-in-out;
}
.scrollbar-thin {
scrollbar-width: thin;
scrollbar-color: hsl(var(--muted-foreground)) transparent;
}
.scrollbar-thin::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.scrollbar-thin::-webkit-scrollbar-track {
background: transparent;
}
.scrollbar-thin::-webkit-scrollbar-thumb {
background-color: hsl(var(--muted-foreground));
border-radius: 3px;
}
.scrollbar-thin::-webkit-scrollbar-thumb:hover {
background-color: hsl(var(--muted-foreground) / 0.8);
}
/* Dark mode scrollbar styles */
.dark .scrollbar-thin {
scrollbar-color: rgba(156, 163, 175, 0.5) transparent;
}
.dark .scrollbar-thin::-webkit-scrollbar-track {
background: rgba(31, 41, 55, 0.3);
}
.dark .scrollbar-thin::-webkit-scrollbar-thumb {
background-color: rgba(156, 163, 175, 0.5);
border-radius: 3px;
}
.dark .scrollbar-thin::-webkit-scrollbar-thumb:hover {
background-color: rgba(156, 163, 175, 0.7);
}
/* Global scrollbar styles for main content areas */
.dark::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.dark::-webkit-scrollbar-track {
background: rgba(31, 41, 55, 0.5);
}
.dark::-webkit-scrollbar-thumb {
background-color: rgba(107, 114, 128, 0.5);
border-radius: 4px;
}
.dark::-webkit-scrollbar-thumb:hover {
background-color: rgba(107, 114, 128, 0.7);
}
/* Firefox scrollbar styles */
.dark {
scrollbar-width: thin;
scrollbar-color: rgba(107, 114, 128, 0.5) rgba(31, 41, 55, 0.5);
}
/* Ensure checkbox styling is preserved */
input[type="checkbox"] {
@apply accent-blue-600;
opacity: 1;
}
input[type="checkbox"]:focus {
opacity: 1;
outline: 2px solid hsl(var(--ring));
outline-offset: 2px;
}
/* Fix checkbox appearance in dark mode */
.dark input[type="checkbox"] {
background-color: rgb(31 41 55); /* gray-800 */
border-color: rgb(75 85 99); /* gray-600 */
color: rgb(37 99 235); /* blue-600 */
color-scheme: dark;
}
.dark input[type="checkbox"]:checked {
background-color: rgb(37 99 235); /* blue-600 */
border-color: rgb(37 99 235); /* blue-600 */
}
.dark input[type="checkbox"]:focus {
--tw-ring-color: rgb(59 130 246); /* blue-500 */
--tw-ring-offset-color: rgb(31 41 55); /* gray-800 */
}
/* Fix radio button appearance in dark mode */
.dark input[type="radio"] {
background-color: rgb(31 41 55); /* gray-800 */
border-color: rgb(75 85 99); /* gray-600 */
color: rgb(37 99 235); /* blue-600 */
color-scheme: dark;
}
.dark input[type="radio"]:checked {
background-color: rgb(37 99 235); /* blue-600 */
border-color: rgb(37 99 235); /* blue-600 */
}
.dark input[type="radio"]:focus {
--tw-ring-color: rgb(59 130 246); /* blue-500 */
--tw-ring-offset-color: rgb(31 41 55); /* gray-800 */
}
/* Ensure textarea text is always visible in dark mode */
textarea {
color-scheme: light dark;
}
.dark textarea {
color: rgb(243 244 246) !important; /* gray-100 */
-webkit-text-fill-color: rgb(243 244 246) !important;
caret-color: rgb(243 244 246) !important;
}
/* Fix for focus state in dark mode */
.dark textarea:focus {
color: rgb(243 244 246) !important;
-webkit-text-fill-color: rgb(243 244 246) !important;
}
/* Fix for iOS/Safari dark mode textarea issues */
@supports (-webkit-touch-callout: none) {
.dark textarea {
background-color: transparent !important;
color: rgb(243 244 246) !important;
-webkit-text-fill-color: rgb(243 244 246) !important;
}
.dark textarea:focus {
background-color: transparent !important;
color: rgb(243 244 246) !important;
-webkit-text-fill-color: rgb(243 244 246) !important;
}
}
/* Ensure parent container doesn't override textarea styles */
.dark .bg-gray-800 textarea {
color: rgb(243 244 246) !important;
-webkit-text-fill-color: rgb(243 244 246) !important;
}
/* Fix focus-within container issues in dark mode */
.dark .focus-within\:ring-2:focus-within {
background-color: rgb(31 41 55) !important; /* gray-800 */
}
/* Ensure textarea remains transparent with visible text */
.dark textarea.bg-transparent {
background-color: transparent !important;
color: rgb(243 244 246) !important;
-webkit-text-fill-color: rgb(243 244 246) !important;
}
/* Fix placeholder text color to be properly gray */
textarea::placeholder {
color: rgb(156 163 175) !important; /* gray-400 */
opacity: 1 !important;
}
.dark textarea::placeholder {
color: rgb(75 85 99) !important; /* gray-600 - darker gray */
opacity: 1 !important;
}
/* More specific selector for chat input textarea */
.dark .bg-gray-800 textarea::placeholder,
.dark textarea.bg-transparent::placeholder {
color: rgb(75 85 99) !important; /* gray-600 - darker gray */
opacity: 1 !important;
-webkit-text-fill-color: rgb(75 85 99) !important;
}
/* Custom class for chat input placeholder */
.chat-input-placeholder::placeholder {
color: rgb(156 163 175) !important;
opacity: 1 !important;
}
.dark .chat-input-placeholder::placeholder {
color: rgb(75 85 99) !important;
opacity: 1 !important;
-webkit-text-fill-color: rgb(75 85 99) !important;
}
.chat-input-placeholder::-webkit-input-placeholder {
color: rgb(156 163 175) !important;
opacity: 1 !important;
}
.dark .chat-input-placeholder::-webkit-input-placeholder {
color: rgb(75 85 99) !important;
opacity: 1 !important;
-webkit-text-fill-color: rgb(75 85 99) !important;
}
/* WebKit specific placeholder styles */
textarea::-webkit-input-placeholder {
color: rgb(156 163 175) !important;
opacity: 1 !important;
}
.dark textarea::-webkit-input-placeholder {
color: rgb(75 85 99) !important; /* gray-600 - darker gray */
opacity: 1 !important;
}
/* Mozilla specific placeholder styles */
textarea::-moz-placeholder {
color: rgb(156 163 175) !important;
opacity: 1 !important;
}
.dark textarea::-moz-placeholder {
color: rgb(75 85 99) !important; /* gray-600 - darker gray */
opacity: 1 !important;
}
/* IE/Edge specific placeholder styles */
textarea:-ms-input-placeholder {
color: rgb(156 163 175) !important;
opacity: 1 !important;
}
.dark textarea:-ms-input-placeholder {
color: rgb(75 85 99) !important; /* gray-600 - darker gray */
opacity: 1 !important;
}
}
/* Mobile optimizations and components */
@layer components {
/* Mobile touch optimization and safe areas */
@media (max-width: 768px) {
* {
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
}
/* Allow vertical scrolling in scroll containers */
.overflow-y-auto, [data-scroll-container] {
touch-action: pan-y;
-webkit-overflow-scrolling: touch;
}
/* Preserve checkbox visibility */
input[type="checkbox"] {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0.1);
opacity: 1 !important;
}
button,
[role="button"],
.clickable,
a,
.cursor-pointer {
-webkit-tap-highlight-color: transparent;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
}
/* Better mobile touch targets */
.mobile-touch-target {
@apply min-h-[44px] min-w-[44px];
}
/* Chat message improvements */
.chat-message.user {
@apply justify-end;
}
.chat-message.user > div {
@apply max-w-[85%];
}
.chat-message.assistant > div,
.chat-message.error > div {
@apply w-full sm:max-w-[95%];
}
/* Session name truncation on mobile */
.session-name-mobile {
@apply truncate;
max-width: calc(100vw - 120px); /* Account for sidebar padding and buttons */
}
/* Enable text selection on mobile for terminal */
.xterm,
.xterm .xterm-viewport {
-webkit-user-select: text !important;
user-select: text !important;
-webkit-touch-callout: default !important;
}
/* Fix mobile scrolling */
.overflow-y-auto {
touch-action: pan-y;
-webkit-overflow-scrolling: touch;
}
.chat-message {
touch-action: pan-y;
}
/* Fix hover states on mobile */
.group:active .group-hover\:opacity-100,
.group .group-hover\:opacity-100 {
opacity: 1 !important;
}
@media (hover: none) and (pointer: coarse) {
.group-hover\:opacity-100 {
opacity: 1 !important;
}
.hover\:bg-gray-50:hover,
.hover\:bg-gray-100:hover,
.hover\:bg-red-200:hover,
.dark\:hover\:bg-gray-700:hover,
.dark\:hover\:bg-red-900\/50:hover {
background-color: inherit;
}
}
}
/* Touch device optimizations for all screen sizes */
@media (hover: none) and (pointer: coarse) {
.touch\:opacity-100 {
opacity: 1 !important;
}
/* Completely disable hover states on touch devices */
* {
-webkit-tap-highlight-color: transparent !important;
}
/* Preserve checkbox visibility on touch devices */
input[type="checkbox"] {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0.1) !important;
opacity: 1 !important;
}
/* Only disable hover states for interactive elements, not containers */
button:hover,
[role="button"]:hover,
.cursor-pointer:hover,
a:hover,
.hover\:bg-gray-50:hover,
.hover\:bg-gray-100:hover,
.hover\:text-gray-900:hover,
.hover\:opacity-100:hover {
background-color: inherit !important;
color: inherit !important;
opacity: inherit !important;
transform: inherit !important;
}
/* Force buttons to be immediately clickable */
button, [role="button"], .cursor-pointer {
cursor: pointer !important;
pointer-events: auto !important;
}
/* Keep active states for immediate feedback */
.active\:scale-\[0\.98\]:active,
.active\:scale-95:active {
transform: scale(0.98) !important;
}
}
/* Safe area support for iOS devices */
.ios-bottom-safe {
padding-bottom: env(safe-area-inset-bottom);
}
/* PWA specific header adjustments - uses CSS variables for consistency */
.pwa-header-safe {
padding-top: var(--header-base-padding);
}
/* When PWA mode is detected by JavaScript */
body.pwa-mode .pwa-header-safe {
/* Reset padding since #root already handles safe area */
padding-top: 0px !important;
}
/* For mobile PWA, add bottom padding for better spacing */
@media screen and (max-width: 768px) {
body.pwa-mode .pwa-header-safe {
padding-bottom: 8px;
}
}
@media screen and (max-width: 768px) {
.chat-input-mobile {
padding-bottom: calc(60px + env(safe-area-inset-bottom));
}
}
/* Text wrapping improvements */
.chat-message {
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
}
/* Force wrap long URLs and code */
.chat-message pre,
.chat-message code {
white-space: pre-wrap !important;
word-break: break-all;
overflow-wrap: break-word;
}
/* Prevent horizontal scroll in chat area */
.chat-message * {
max-width: 100%;
box-sizing: border-box;
}
/* Hide scrollbar utility for horizontal scroll */
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
}
/* Hide markdown backticks in prose content */
.prose code::before,
.prose code::after {
content: "" !important;
display: none !important;
}
/* Custom spinner animation for mobile compatibility */
@layer utilities {
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.animate-spin {
animation: spin 1s linear infinite;
}
/* Force hardware acceleration for smoother animation on mobile */
.loading-spinner {
animation: spin 1s linear infinite;
will-change: transform;
transform: translateZ(0);
-webkit-transform: translateZ(0);
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
/* Improved textarea styling */
.chat-input-placeholder {
display: block !important;
scrollbar-width: thin;
scrollbar-color: rgba(156, 163, 175, 0.3) transparent;
}
/* Ensure container fits textarea tightly */
.chat-input-placeholder:not(:focus) {
height: auto;
}
.chat-input-placeholder::-webkit-scrollbar {
width: 6px;
}
.chat-input-placeholder::-webkit-scrollbar-track {
background: transparent;
margin: 8px 0;
}
.chat-input-placeholder::-webkit-scrollbar-thumb {
background-color: rgba(156, 163, 175, 0.3);
border-radius: 3px;
transition: background-color 0.2s;
}
.chat-input-placeholder::-webkit-scrollbar-thumb:hover {
background-color: rgba(156, 163, 175, 0.5);
}
.dark .chat-input-placeholder {
scrollbar-color: rgba(107, 114, 128, 0.3) transparent;
}
.dark .chat-input-placeholder::-webkit-scrollbar-thumb {
background-color: rgba(107, 114, 128, 0.3);
}
.dark .chat-input-placeholder::-webkit-scrollbar-thumb:hover {
background-color: rgba(107, 114, 128, 0.5);
}
/* Enhanced box shadow when textarea expands */
.chat-input-expanded {
box-shadow: 0 -5px 15px -3px rgba(0, 0, 0, 0.1), 0 -4px 6px -2px rgba(0, 0, 0, 0.05);
}
.dark .chat-input-expanded {
box-shadow: 0 -5px 15px -3px rgba(0, 0, 0, 0.3), 0 -4px 6px -2px rgba(0, 0, 0, 0.2);
}
/* Fix focus ring offset color in dark mode */
.dark [class*="ring-offset"] {
--tw-ring-offset-color: rgb(31 41 55); /* gray-800 */
}
/* Ensure buttons don't show white backgrounds in dark mode */
.dark button:focus {
--tw-ring-offset-color: rgb(31 41 55); /* gray-800 */
}
/* Fix mobile select dropdown styling */
@supports (-webkit-touch-callout: none) {
select {
font-size: 16px !important;
-webkit-appearance: none;
}
}
/* Improve select appearance in dark mode */
.dark select {
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239CA3AF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 0.5rem center;
background-size: 1.5em 1.5em;
padding-right: 2.5rem;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
select {
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 0.5rem center;
background-size: 1.5em 1.5em;
padding-right: 2.5rem;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
/* Fix select option text in mobile */
select option {
font-size: 16px !important;
padding: 8px !important;
background-color: var(--background) !important;
color: var(--foreground) !important;
}
.dark select option {
background-color: rgb(31 41 55) !important;
color: rgb(243 244 246) !important;
}
/* Tool details chevron animation */
details[open] .details-chevron,
details[open] summary svg[class*="group-open"] {
transform: rotate(180deg);
}
/* Smooth chevron transition */
.details-chevron,
summary svg[class*="transition-transform"] {
transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* Search result highlight flash */
.search-highlight-flash {
animation: search-flash 4s ease-out;
}
@keyframes search-flash {
0%, 50% {
outline: 3px solid hsl(var(--primary));
outline-offset: 4px;
border-radius: 8px;
background-color: hsl(var(--primary) / 0.06);
}
100% {
outline: 3px solid transparent;
outline-offset: 4px;
background-color: transparent;
}
}
}