@tailwind base; @tailwind components; @tailwind utilities; /* ═══════════════════════════════════════════════ Design System: CSS Custom Properties Refined dark palette with proper depth hierarchy ═══════════════════════════════════════════════ */ @layer base { :root { /* Surfaces — clear elevation hierarchy */ --color-surface: #14181f; --color-surface-raised: #1a1f2b; --color-surface-overlay: #242a38; --color-surface-inset: #0f1218; /* Borders — subtle separation */ --color-border: #2a3140; --color-border-muted: #1e2433; /* Foreground — text hierarchy */ --color-foreground: #e8edf5; --color-foreground-secondary: #8d96a8; --color-foreground-muted: #505a6e; /* Accent — refined blue with depth */ --color-accent: #5b9cf5; --color-accent-light: #162544; --color-accent-dark: #7db4ff; /* Layout background — deepest layer */ --color-canvas: #0c1017; /* Glow/highlight colors */ --color-glow-accent: rgba(91, 156, 245, 0.12); --color-glow-success: rgba(63, 185, 80, 0.12); /* Inter font from Google Fonts CDN */ font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-feature-settings: "cv02", "cv03", "cv04", "cv11"; } /* Smooth transitions on all interactive elements */ button, a, input, [role="button"] { transition-property: color, background-color, border-color, box-shadow, opacity, transform; transition-duration: 150ms; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); } } /* ═══════════════════════════════════════════════ Custom scrollbar — thin, minimal, with fade ═══════════════════════════════════════════════ */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: var(--color-foreground-muted); } /* Firefox */ * { scrollbar-width: thin; scrollbar-color: var(--color-border) transparent; } /* ═══════════════════════════════════════════════ Glass / frosted overlays ═══════════════════════════════════════════════ */ .glass { background: rgba(26, 31, 43, 0.82); backdrop-filter: blur(16px) saturate(180%); -webkit-backdrop-filter: blur(16px) saturate(180%); } .glass-subtle { background: rgba(20, 24, 31, 0.65); backdrop-filter: blur(12px) saturate(160%); -webkit-backdrop-filter: blur(12px) saturate(160%); } /* ═══════════════════════════════════════════════ Code blocks — refined syntax highlighting ═══════════════════════════════════════════════ */ .hljs { background: var(--color-surface-inset); padding: 1rem; border-radius: 0.5rem; border: 1px solid var(--color-border-muted); overflow-x: auto; font-size: 0.8125rem; line-height: 1.6; white-space: pre-wrap; word-break: break-word; box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2); } /* Code block container with language label + copy button */ .code-block-wrapper { position: relative; margin: 0.75rem 0; } .code-block-wrapper .code-lang-label { position: absolute; top: 0; right: 0; padding: 0.25rem 0.625rem; font-size: 0.6875rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-foreground-muted); background: var(--color-surface-inset); border-bottom-left-radius: 0.375rem; border-top-right-radius: 0.5rem; border-left: 1px solid var(--color-border-muted); border-bottom: 1px solid var(--color-border-muted); } .code-block-wrapper .code-copy-btn { position: absolute; top: 0.375rem; right: 0.375rem; padding: 0.25rem 0.5rem; font-size: 0.6875rem; color: var(--color-foreground-muted); background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: 0.25rem; cursor: pointer; opacity: 0; transition: opacity 150ms, background-color 150ms, color 150ms; } /* When a language label is present, shift copy button below it */ .code-block-wrapper .code-lang-label + .code-copy-btn, .code-block-wrapper:has(.code-lang-label) .code-copy-btn { top: 2rem; } .code-block-wrapper:hover .code-copy-btn { opacity: 1; } .code-block-wrapper .code-copy-btn:hover { color: var(--color-foreground); background: var(--color-surface-overlay); } /* ═══════════════════════════════════════════════ Diff view — colored line-level highlighting ═══════════════════════════════════════════════ */ .diff-view { font-size: 0.8125rem; line-height: 1.6; } .diff-add { background: rgba(63, 185, 80, 0.12); color: #3fb950; display: block; margin: 0 -1rem; padding: 0 1rem; } .diff-del { background: rgba(248, 81, 73, 0.12); color: #f85149; display: block; margin: 0 -1rem; padding: 0 1rem; } .diff-hunk { color: #79c0ff; display: block; margin: 0 -1rem; padding: 0.25rem 1rem; background: rgba(121, 192, 255, 0.06); } .diff-meta { color: var(--color-foreground-muted); font-weight: 600; display: block; } .diff-header { color: var(--color-foreground-secondary); font-weight: 600; display: block; margin: 0 -1rem; padding: 0.25rem 1rem; background: rgba(136, 144, 245, 0.06); } /* ═══════════════════════════════════════════════ Search highlight — warm amber glow ═══════════════════════════════════════════════ */ mark.search-highlight { background: rgba(250, 204, 21, 0.2); color: inherit; padding: 1px 3px; border-radius: 3px; box-shadow: 0 0 0 1px rgba(250, 204, 21, 0.35), 0 0 8px rgba(250, 204, 21, 0.08); } .search-match-focused { outline: 2px solid #f59e0b; outline-offset: 2px; box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.15); } /* ═══════════════════════════════════════════════ Search minimap — scrollbar tick track ═══════════════════════════════════════════════ */ .search-minimap { position: absolute; top: 0; right: 0; width: 8px; height: 100%; pointer-events: none; z-index: 10; } .search-minimap-tick { position: absolute; right: 0; width: 8px; height: 3px; background: rgba(254, 240, 138, 0.7); border: none; padding: 0; cursor: pointer; pointer-events: auto; border-radius: 1px; transition: background-color 150ms, height 150ms, box-shadow 150ms; } .search-minimap-tick:hover { background: #fde047; box-shadow: 0 0 4px rgba(253, 224, 71, 0.4); } .search-minimap-viewport { position: absolute; right: 0; width: 8px; background: rgba(148, 163, 184, 0.18); border-radius: 1px; pointer-events: none; transition: top 60ms linear, height 60ms linear; min-height: 4px; } .search-minimap-tick-active { background: #f59e0b; height: 6px; box-shadow: 0 0 6px rgba(245, 158, 11, 0.5); } /* ═══════════════════════════════════════════════ Redaction selection indicator ═══════════════════════════════════════════════ */ .redaction-selected { outline: 2px solid #ef4444; outline-offset: 2px; background-image: repeating-linear-gradient( -45deg, transparent, transparent 4px, rgba(239, 68, 68, 0.06) 4px, rgba(239, 68, 68, 0.06) 8px ); } /* ═══════════════════════════════════════════════ Message dimming for search ═══════════════════════════════════════════════ */ .message-dimmed { opacity: 0.35; transition: opacity 200ms ease; } .message-dimmed:hover { opacity: 0.65; } /* ═══════════════════════════════════════════════ Skeleton loading animation — refined shimmer ═══════════════════════════════════════════════ */ .skeleton { background: linear-gradient( 90deg, var(--color-border-muted) 0%, var(--color-border) 40%, var(--color-border-muted) 80% ); background-size: 300% 100%; animation: skeletonShimmer 1.8s ease-in-out infinite; border-radius: 0.375rem; } @keyframes skeletonShimmer { 0% { background-position: 200% 0; } 100% { background-position: -100% 0; } } /* ═══════════════════════════════════════════════ Prose overrides for message content ═══════════════════════════════════════════════ */ .prose-message h1 { font-size: 1.25rem; font-weight: 600; margin-top: 1.25rem; margin-bottom: 0.5rem; letter-spacing: -0.02em; color: var(--color-foreground); } .prose-message h2 { font-size: 1.125rem; font-weight: 600; margin-top: 1rem; margin-bottom: 0.375rem; letter-spacing: -0.01em; color: var(--color-foreground); } .prose-message h3 { font-size: 1rem; font-weight: 600; margin-top: 0.875rem; margin-bottom: 0.375rem; color: var(--color-foreground); } .prose-message p { margin-top: 0.5rem; margin-bottom: 0.5rem; line-height: 1.6; } .prose-message p:first-child { margin-top: 0; } .prose-message p:last-child { margin-bottom: 0; } .prose-message ul, .prose-message ol { margin-top: 0.5rem; margin-bottom: 0.5rem; padding-left: 1.25rem; } .prose-message li { margin-top: 0.25rem; margin-bottom: 0.25rem; line-height: 1.6; } .prose-message code:not(pre code) { font-family: "JetBrains Mono", "Fira Code", "SF Mono", ui-monospace, monospace; font-size: 0.8125em; padding: 0.125rem 0.375rem; border-radius: 0.25rem; background: var(--color-surface-inset); border: 1px solid var(--color-border-muted); color: #c4a1ff; font-weight: 500; } .prose-message pre { margin-top: 0.75rem; margin-bottom: 0.75rem; max-width: 100%; overflow-x: auto; } .prose-message blockquote { border-left: 3px solid var(--color-border); padding-left: 0.75rem; color: var(--color-foreground-secondary); margin-top: 0.5rem; margin-bottom: 0.5rem; } .prose-message a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: rgba(91, 156, 245, 0.3); transition: text-decoration-color 150ms; } .prose-message a:hover { color: var(--color-accent-dark); text-decoration-color: rgba(125, 180, 255, 0.6); } .prose-message table { width: 100%; border-collapse: collapse; margin-top: 0.75rem; margin-bottom: 0.75rem; font-size: 0.8125rem; } .prose-message th, .prose-message td { border: 1px solid var(--color-border-muted); padding: 0.375rem 0.75rem; text-align: left; } .prose-message th { background: var(--color-surface-inset); font-weight: 600; } /* ═══════════════════════════════════════════════ Progress markdown (compact variant) ═══════════════════════════════════════════════ */ .prose-message-progress { font-family: "JetBrains Mono", "Fira Code", "SF Mono", ui-monospace, monospace; font-size: 11px; line-height: 1.5; color: var(--color-foreground-secondary); word-break: break-word; } .prose-message-progress h1, .prose-message-progress h2, .prose-message-progress h3, .prose-message-progress h4, .prose-message-progress h5, .prose-message-progress h6 { font-size: 12px; font-weight: 600; color: var(--color-foreground); margin-top: 0.25rem; margin-bottom: 0.25rem; } .prose-message-progress p { margin-top: 0.125rem; margin-bottom: 0.125rem; } .prose-message-progress p:first-child { margin-top: 0; } .prose-message-progress p:last-child { margin-bottom: 0; } .prose-message-progress ul, .prose-message-progress ol { margin-top: 0.25rem; margin-bottom: 0.25rem; padding-left: 1rem; } .prose-message-progress li { margin-top: 0.125rem; margin-bottom: 0.125rem; line-height: 1.5; } .prose-message-progress code:not(pre code) { font-family: inherit; font-size: 0.9em; padding: 0.0625rem 0.25rem; border-radius: 0.1875rem; background: var(--color-surface-inset); border: 1px solid var(--color-border-muted); color: #c4a1ff; font-weight: 500; } .prose-message-progress pre { margin-top: 0.5rem; margin-bottom: 0.5rem; max-width: 100%; overflow-x: auto; } .prose-message-progress blockquote { border-left: 2px solid var(--color-border); padding-left: 0.5rem; color: var(--color-foreground-secondary); margin-top: 0.25rem; margin-bottom: 0.25rem; } .prose-message-progress a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: rgba(91, 156, 245, 0.3); transition: text-decoration-color 150ms; } .prose-message-progress a:hover { color: var(--color-accent-dark); text-decoration-color: rgba(125, 180, 255, 0.6); } .prose-message-progress table { width: 100%; border-collapse: collapse; margin-top: 0.375rem; margin-bottom: 0.375rem; font-size: 11px; } .prose-message-progress th, .prose-message-progress td { border: 1px solid var(--color-border-muted); padding: 0.25rem 0.5rem; text-align: left; } .prose-message-progress th { background: var(--color-surface-inset); font-weight: 600; } /* ═══════════════════════════════════════════════ Focus ring system ═══════════════════════════════════════════════ */ :focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; } /* Custom checkbox styling */ .custom-checkbox { appearance: none; width: 1rem; height: 1rem; border: 1.5px solid var(--color-border); border-radius: 0.25rem; background: var(--color-surface); cursor: pointer; flex-shrink: 0; transition: all 150ms; position: relative; } .custom-checkbox:hover { border-color: var(--color-foreground-muted); } .custom-checkbox:checked { background: var(--color-accent); border-color: var(--color-accent); box-shadow: 0 0 0 2px rgba(91, 156, 245, 0.15); } .custom-checkbox:checked::after { content: ""; position: absolute; top: 6.25%; left: 25%; width: 31.25%; height: 56.25%; border: solid #0c1017; border-width: 0 2px 2px 0; transform: rotate(45deg); } .custom-checkbox.checkbox-danger:checked { background: #ef4444; border-color: #ef4444; box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.15); } /* ═══════════════════════════════════════════════ Button system ═══════════════════════════════════════════════ */ @layer components { .btn { @apply inline-flex items-center justify-center font-medium rounded-lg transition-all; @apply focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2; @apply active:scale-[0.97]; --tw-ring-offset-color: var(--color-surface); } .btn-sm { @apply px-3 py-1.5 text-caption; } .btn-md { @apply px-4 py-2 text-body; } .btn-primary { background: linear-gradient(135deg, #5b9cf5, #4a8be0); @apply text-white; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.08); @apply hover:brightness-110; @apply disabled:opacity-50 disabled:cursor-not-allowed; @apply focus-visible:ring-accent; } .btn-secondary { @apply bg-surface-raised text-foreground-secondary border border-border; @apply hover:bg-surface-overlay hover:text-foreground; @apply disabled:opacity-50 disabled:cursor-not-allowed; @apply focus-visible:ring-accent; } .btn-secondary:hover { border-color: rgba(80, 90, 110, 0.3); } .btn-ghost { @apply text-foreground-secondary; @apply hover:bg-surface-overlay hover:text-foreground; @apply disabled:opacity-50 disabled:cursor-not-allowed; @apply focus-visible:ring-accent; } .btn-danger { background: linear-gradient(135deg, #dc2626, #c42020); @apply text-white; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.06); @apply hover:brightness-110; @apply disabled:opacity-50 disabled:cursor-not-allowed; @apply focus-visible:ring-red-500; } } /* ═══════════════════════════════════════════════ Tooltip ═══════════════════════════════════════════════ */ .tooltip-popup { pointer-events: none; max-width: 280px; padding: 0.375rem 0.625rem; font-size: 0.75rem; line-height: 1.45; color: var(--color-foreground); background: var(--color-surface-overlay); border: 1px solid var(--color-border); border-radius: 0.375rem; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(0, 0, 0, 0.1); animation: tooltip-in 120ms cubic-bezier(0.16, 1, 0.3, 1); white-space: normal; } .tooltip-popup[data-side="top"] { transform-origin: bottom center; translate: -50% -100%; } .tooltip-popup[data-side="bottom"] { transform-origin: top center; translate: -50% 0; } @keyframes tooltip-in { from { opacity: 0; scale: 0.96; } to { opacity: 1; scale: 1; } }