Files
claudecodeui/src/index.css
Haile 7eb7348d50 Feat/design improvements and minor bug fixes (#939)
* fix(shell): hide prompt options on desktop

* fix(chat): group continuous same-tool runs more consistently

Consecutive tool calls (Edit, Read, Grep, etc.) grouped inconsistently:

- The group threshold was 3, so a run of only 2 calls stayed ungrouped
  while a run of 3 collapsed — making two back-to-back edits look
  different from three.
- A run was broken by any interleaved message, including ones that render
  nothing (reasoning hidden when showThinking is off). Providers like
  Codex interleave hidden reasoning between tool calls, so visually
  continuous edits intermittently failed to group.

Lower TOOL_GROUP_THRESHOLD to 2 and skip non-rendered messages when
extending a run, so any 2+ consecutive same-tool calls collapse reliably.
ChatMessagesPane now passes showThinking into groupConsecutiveTools.

* fix(chat): stabilize message scroll controls

* fix: update command menu positioning

* fix(chat): refine load all overlay behavior

* fix(chat): hide load all prompt after final page

* fix(chat): remove auto scroll quick setting

* fix(chat): unify messages and composer into centered column

Constrain both ChatMessagesPane content and ChatComposer to the same
max-w-3xl centered column. Previously only
the composer had a max-width, causing messages to fill the full width
while the input stayed narrow, making them visually misaligned with
large empty gutters on either side.

* style(ui): rework light/dark theme to make it visually consistent

Rework the color system around warm neutrals and route hardcoded
surfaces through theme tokens for consistency.

- Theme tokens (index.css, ThemeContext): warm cream light mode and
  neutral charcoal dark mode, replacing the pure-white/blue-tinted
  palette; update PWA theme-color meta
- Code blocks: soft grey background in light mode via
  oneLight/oneDark, and drop the Tailwind Typography <pre> shell that
  framed the highlighter in a dark box
- Dropdowns/panels: convert CommandMenu, Quick Settings, and the JSON
  response block from hardcoded gray/slate to popover/muted/border
  tokens
- Git panel: Publish button purple -> primary blue
- Composer: drop top padding so the input sits flush with the thread

* fix: use app theme for code editor

* style(chat): unify composer toolbar heights and declutter slash-command modal

- Composer: give the permission-mode and token-usage buttons a fixed
  h-8 so every bottom-toolbar control shares one height
- CommandResultModal: replace the blue gradient header (gradient fill,
  glow blobs, blue eyebrow + icon chip) with a clean neutral header on
  popover/muted tokens

* fix(chat): header ellipsis, Codex logo on light theme, portal copy menu

- MainContentTitle: truncate the session title with an ellipsis instead
  of horizontal-scrolling it
- MessageComponent: use text-foreground for the provider logo chip so the
  currentColor Codex/OpenAI mark is visible on the light theme
- MessageCopyControl: render the copy-format dropdown in a portal so it
  escapes the chat message's `contain: paint` clip box; anchor it to the
  trigger, flip above near the viewport bottom, close on scroll/resize

* style(mcp): remove purple accents and portal the server form modal

- Replace the purple provider-button colors, heading icon, and form
  submit button with the primary token (no purple in the MCP UI)
- Portal the add/edit MCP server modal to document.body so its fixed
  overlay covers the full viewport, fixing the white band at the top
  caused by the Settings dialog's transformed tab content becoming the
  containing block

* style(ui): use Merriweather serif for chat text and Encode Sans for the rest of the UI

* fix: align activity indicator with composer input width

Wrap ActivityIndicator in the same mx-auto max-w-3xl container as the
text input so the "Analyzing…" label and Stop button stay within the
input's boundaries instead of spanning the full window width.

* style: improve thinking and stop button placements

* style(auth): modernize login, setup, and onboarding screens

* fix(chat): correct invalid dark-mode hover on AskUserQuestion options

* fix: remove unnecessary auto expand tools

* fix: resolve coderabbit comments

* fix(chat): widen chat layout and sidebar titles

* fix(branding): update CloudCLI wordmark styling

---------

Co-authored-by: Simos Mikelatos <simosmik@gmail.com>
2026-07-01 13:57:03 +02:00

1017 lines
27 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: 44 22% 96%;
--foreground: 36 25% 4%;
--card: 0 0% 100%;
--card-foreground: 36 25% 4%;
--popover: 0 0% 100%;
--popover-foreground: 36 25% 4%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--secondary: 44 15% 91%;
--secondary-foreground: 36 15% 18%;
--muted: 44 15% 91%;
--muted-foreground: 40 5% 44%;
--accent: 44 15% 91%;
--accent-foreground: 36 15% 18%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 44 14% 87%;
--input: 44 14% 87%;
--ring: 221.2 83.2% 53.3%;
--radius: 0.5rem;
/* Nav design tokens */
--nav-glass-bg: 44 22% 96% / 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: 44 14% 87% / 0.5;
--nav-divider-color: 44 14% 87% / 0.5;
--nav-input-bg: 44 15% 91% / 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: 0 0% 8%;
--foreground: 40 8% 93%;
--card: 0 0% 12%;
--card-foreground: 40 8% 93%;
--popover: 0 0% 12%;
--popover-foreground: 40 8% 93%;
--primary: 217.2 91.2% 59.8%;
--primary-foreground: 0 0% 8%;
--secondary: 0 0% 17%;
--secondary-foreground: 40 8% 93%;
--muted: 0 0% 17%;
--muted-foreground: 0 0% 60%;
--accent: 0 0% 17%;
--accent-foreground: 40 8% 93%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 40 8% 93%;
--border: 0 0% 17%;
--input: 0 0% 23%;
--ring: 217.2 91.2% 59.8%;
/* Nav design tokens — dark overrides */
--nav-glass-bg: 0 0% 12% / 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: 0 0% 17% / 0.3;
--nav-divider-color: 0 0% 17% / 0.5;
--nav-input-bg: 0 0% 17% / 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: "Encode Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
/* The app shell is a fixed inset-0 container (see AppContent), so the
document itself never needs to scroll. Clipping it removes the phantom
full-height page scrollbar and disables the browser pull-to-refresh
gesture that reloads the page when scrolling up on mobile. */
overflow: hidden;
overscroll-behavior-y: contain;
}
/* 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(38, 38, 38, 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(38, 38, 38, 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(115, 115, 115, 0.5) rgba(38, 38, 38, 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(20 20 20) !important;
}
/* 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 {
.chat-messages-pane {
contain: layout style paint;
}
.chat-composer-shell {
contain: layout style;
}
.chat-activity-enter {
animation: chat-activity-enter 320ms cubic-bezier(0.22, 1, 0.36, 1) both;
transform-origin: bottom center;
will-change: transform, opacity, filter;
}
.chat-activity-exit {
animation: chat-activity-exit 220ms cubic-bezier(0.4, 0, 1, 1) both;
transform-origin: bottom center;
will-change: transform, opacity, filter;
}
.chat-activity-tab {
clip-path: inset(-8px -8px 0 -8px);
}
.chat-message {
contain: layout style paint;
content-visibility: auto;
contain-intrinsic-size: auto 180px;
}
.chat-message.assistant {
contain-intrinsic-size: auto 240px;
}
.chat-message.user,
.chat-message.tool,
.chat-message.error {
contain-intrinsic-size: auto 96px;
}
/* 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(20 20 20);
}
/* Ensure buttons don't show white backgrounds in dark mode */
.dark button:focus {
--tw-ring-offset-color: rgb(20 20 20);
}
/* 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 31 31) !important;
color: rgb(237 235 230) !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);
}
/* Settings content fade-in transition */
@keyframes settings-fade-in {
from { opacity: 0; transform: translateY(4px); }
to { opacity: 1; transform: translateY(0); }
}
.settings-content-enter {
animation: settings-fade-in 150ms ease-out;
}
@keyframes chat-activity-enter {
0% {
opacity: 0;
filter: blur(3px);
transform: translateY(18px) scaleY(0.92);
}
65% {
opacity: 1;
filter: blur(0);
transform: translateY(-2px) scaleY(1.01);
}
100% {
opacity: 1;
filter: blur(0);
transform: translateY(0) scaleY(1);
}
}
@keyframes chat-activity-exit {
0% {
opacity: 1;
filter: blur(0);
transform: translateY(0) scaleY(1);
}
100% {
opacity: 0;
filter: blur(2px);
transform: translateY(14px) scaleY(0.96);
}
}
/* 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;
}
}
}