Introduce IntegrateCommitsSection to plan and apply commits from source to target branch Wire the integration panel into GitView so users can run integrate flow from the current worktree
668 lines
16 KiB
CSS
668 lines
16 KiB
CSS
@import "tailwindcss";
|
|
@import "tw-animate-css";
|
|
@import "./styles/design-system.css";
|
|
@import "./styles/typography.css";
|
|
@import "./styles/mobile.css";
|
|
@source "./**/*.{ts,tsx,css}";
|
|
|
|
@custom-variant dark (&:is(.dark *));
|
|
|
|
/* Suppress WebKit-specific hover/focus adornments on the chat textarea */
|
|
textarea[data-chat-input="true"] {
|
|
-webkit-appearance: none;
|
|
background: transparent !important;
|
|
border: none;
|
|
box-shadow: none;
|
|
}
|
|
|
|
textarea[data-chat-input="true"]:focus,
|
|
textarea[data-chat-input="true"]:focus-visible,
|
|
textarea[data-chat-input="true"]:hover {
|
|
outline: none;
|
|
border: none;
|
|
box-shadow: none;
|
|
}
|
|
|
|
.oc-cm-selected-line {
|
|
background: color-mix(in srgb, var(--accent) 70%, transparent);
|
|
}
|
|
|
|
.oc-plan-editor .cm-scroller,
|
|
.oc-plan-editor .cm-content,
|
|
.oc-plan-editor .cm-gutters {
|
|
font-family: "IBM Plex Sans", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif !important;
|
|
}
|
|
|
|
:root.vscode-runtime textarea[data-chat-input="true"]::placeholder {
|
|
color: color-mix(in srgb, var(--vscode-input-placeholderForeground, var(--muted-foreground)) 65%, transparent);
|
|
}
|
|
|
|
/* Match chat footer background to input in WebKit to avoid dual-tone hover/focus */
|
|
[data-chat-input="true"] + div[data-chat-input-footer="true"] {
|
|
background: transparent !important;
|
|
border: none;
|
|
box-shadow: none;
|
|
-webkit-appearance: none;
|
|
}
|
|
|
|
[data-keyboard-avoid-active="true"] {
|
|
transform: translateY(calc(-1 * var(--oc-keyboard-avoid-offset, 0px)));
|
|
}
|
|
|
|
/* Scroll shadow (HeroUI) fallback styling to ensure visible gradients without the Tailwind plugin */
|
|
[data-scroll-shadow="true"] {
|
|
--scroll-shadow-size: var(--scroll-shadow-size, 48px);
|
|
}
|
|
|
|
[data-scroll-shadow="true"][data-orientation="vertical"] {
|
|
mask-mode: alpha;
|
|
}
|
|
|
|
[data-scroll-shadow="true"][data-orientation="vertical"][data-top-bottom-scroll="true"] {
|
|
mask-image: linear-gradient(
|
|
to bottom,
|
|
transparent 0%,
|
|
#000 var(--scroll-shadow-size),
|
|
#000 calc(100% - var(--scroll-shadow-size)),
|
|
transparent 100%
|
|
);
|
|
}
|
|
|
|
[data-scroll-shadow="true"][data-orientation="vertical"][data-top-scroll="true"] {
|
|
mask-image: linear-gradient(
|
|
to bottom,
|
|
transparent 0%,
|
|
#000 var(--scroll-shadow-size),
|
|
#000 100%
|
|
);
|
|
}
|
|
|
|
[data-scroll-shadow="true"][data-orientation="vertical"][data-bottom-scroll="true"] {
|
|
mask-image: linear-gradient(
|
|
to bottom,
|
|
#000 0%,
|
|
#000 calc(100% - var(--scroll-shadow-size)),
|
|
transparent 100%
|
|
);
|
|
}
|
|
|
|
|
|
@keyframes spin-once {
|
|
from {
|
|
transform: rotate(0deg);
|
|
}
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
@keyframes oc-migrate-up {
|
|
0% {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
100% {
|
|
opacity: 0;
|
|
transform: translateY(-10px);
|
|
}
|
|
}
|
|
|
|
@keyframes gradient-shimmer {
|
|
0% {
|
|
stop-color: currentColor;
|
|
}
|
|
50% {
|
|
stop-color: color-mix(in srgb, currentColor 60%, white 40%);
|
|
}
|
|
100% {
|
|
stop-color: currentColor;
|
|
}
|
|
}
|
|
|
|
@keyframes shimmer-position {
|
|
0% {
|
|
x: -100%;
|
|
}
|
|
100% {
|
|
x: 100%;
|
|
}
|
|
}
|
|
|
|
@keyframes oc-file-mention-marquee {
|
|
0% {
|
|
transform: translateX(0%);
|
|
}
|
|
100% {
|
|
transform: translateX(calc(-100% + var(--file-mention-marquee-width, 360px)));
|
|
}
|
|
}
|
|
|
|
.file-mention-marquee-container {
|
|
--file-mention-marquee-width: 360px;
|
|
--file-mention-marquee-duration: 4s;
|
|
}
|
|
|
|
.file-mention-marquee {
|
|
animation: oc-file-mention-marquee var(--file-mention-marquee-duration, 4s) linear 0.2s 1 both;
|
|
will-change: transform;
|
|
}
|
|
|
|
/* Safari/WebKit fixes for buttons and SVG icons */
|
|
/* Remixicon puts fill="currentColor" on root SVG which WebKit renders as background */
|
|
button svg.remixicon,
|
|
[role="button"] svg.remixicon,
|
|
button svg,
|
|
[role="button"] svg {
|
|
background: none !important;
|
|
background-color: transparent !important;
|
|
/* Override inline fill attribute on SVG root */
|
|
fill: none !important;
|
|
/* Ensure SVG uses CSS rendering, not native */
|
|
shape-rendering: geometricPrecision;
|
|
}
|
|
|
|
/* GPU acceleration for non-spinning SVGs */
|
|
button svg:not(.animate-spin),
|
|
[role="button"] svg:not(.animate-spin) {
|
|
transform: translateZ(0);
|
|
-webkit-transform: translateZ(0);
|
|
}
|
|
|
|
/* Fix SVG elements inside buttons - remove any rect/circle backgrounds */
|
|
button svg rect,
|
|
button svg circle,
|
|
[role="button"] svg rect,
|
|
[role="button"] svg circle {
|
|
fill: none !important;
|
|
}
|
|
|
|
/* Ensure SVG paths/shapes inherit color properly */
|
|
button svg.remixicon path,
|
|
button svg.remixicon circle[fill],
|
|
[role="button"] svg.remixicon path,
|
|
[role="button"] svg.remixicon circle[fill],
|
|
button svg path,
|
|
[role="button"] svg path {
|
|
fill: currentColor !important;
|
|
}
|
|
|
|
/* Safari/WebKit animation fixes - outside @layer for higher specificity */
|
|
.animate-spin {
|
|
animation: webkit-spin 1s linear infinite !important;
|
|
will-change: transform !important;
|
|
background: transparent !important;
|
|
background-color: transparent !important;
|
|
}
|
|
|
|
/* Specific SVG spinner fixes for WebKit */
|
|
svg.animate-spin {
|
|
/* Use CSS box as transform reference for proper centering with scaled SVGs */
|
|
transform-box: fill-box !important;
|
|
transform-origin: 50% 50% !important;
|
|
background: none !important;
|
|
background-color: transparent !important;
|
|
overflow: visible !important;
|
|
/* Ensure SVG content is centered */
|
|
display: block !important;
|
|
}
|
|
|
|
@keyframes webkit-spin {
|
|
0% {
|
|
transform: translateZ(0) rotate(0deg);
|
|
}
|
|
100% {
|
|
transform: translateZ(0) rotate(360deg);
|
|
}
|
|
}
|
|
|
|
.app-region-drag {
|
|
-webkit-app-region: drag;
|
|
}
|
|
|
|
.app-region-no-drag {
|
|
-webkit-app-region: no-drag;
|
|
}
|
|
|
|
.animate-spin-once {
|
|
animation: spin-once 0.5s linear forwards;
|
|
}
|
|
|
|
/* Custom scrollbar styles */
|
|
*::-webkit-scrollbar {
|
|
width: 10px !important;
|
|
height: 10px !important;
|
|
background: transparent;
|
|
-webkit-appearance: none;
|
|
}
|
|
|
|
*::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
|
|
*::-webkit-scrollbar-thumb {
|
|
background: var(--oc-scrollbar-thumb);
|
|
border-radius: 6px;
|
|
border: 2px solid transparent;
|
|
background-clip: padding-box;
|
|
}
|
|
|
|
*::-webkit-scrollbar-thumb:hover {
|
|
background: var(--oc-scrollbar-thumb-hover);
|
|
background-clip: padding-box;
|
|
}
|
|
|
|
.dark {
|
|
color-scheme: dark;
|
|
--oc-scrollbar-thumb: oklch(0.6 0.02 80 / 0.3);
|
|
--oc-scrollbar-thumb-hover: oklch(0.6 0.02 80 / 0.5);
|
|
}
|
|
|
|
[data-scrollbar="chat"]::-webkit-scrollbar-thumb {
|
|
border: 2px solid transparent;
|
|
background-clip: padding-box;
|
|
}
|
|
|
|
*::-webkit-scrollbar-corner {
|
|
background: transparent;
|
|
}
|
|
|
|
[data-scrollbar="chat"].chat-scroll,
|
|
.chat-scroll {
|
|
scrollbar-gutter: stable both-edges;
|
|
}
|
|
|
|
html:not(.dark) .chat-scroll {
|
|
color-scheme: dark;
|
|
}
|
|
|
|
[data-scrollbar="chat"]::-webkit-scrollbar {
|
|
width: 10px !important;
|
|
height: 10px !important;
|
|
background: transparent !important;
|
|
-webkit-appearance: none;
|
|
}
|
|
|
|
[data-scrollbar="chat"].chat-scroll::-webkit-scrollbar,
|
|
.chat-scroll::-webkit-scrollbar {
|
|
width: 10px !important;
|
|
height: 10px !important;
|
|
}
|
|
|
|
[data-scrollbar="chat"]::-webkit-scrollbar-track {
|
|
background: transparent !important;
|
|
}
|
|
|
|
[data-scrollbar="chat"].chat-scroll::-webkit-scrollbar-track,
|
|
.chat-scroll::-webkit-scrollbar-track {
|
|
background: transparent !important;
|
|
}
|
|
|
|
[data-scrollbar="chat"]::-webkit-scrollbar-thumb {
|
|
background: var(--oc-scrollbar-thumb) !important;
|
|
border-radius: 6px;
|
|
border: 2px solid transparent;
|
|
background-clip: padding-box;
|
|
}
|
|
|
|
[data-scrollbar="chat"].chat-scroll::-webkit-scrollbar-thumb,
|
|
.chat-scroll::-webkit-scrollbar-thumb {
|
|
background: var(--oc-scrollbar-thumb) !important;
|
|
border-radius: 6px;
|
|
border: 2px solid transparent;
|
|
background-clip: padding-box;
|
|
}
|
|
|
|
[data-scrollbar="chat"]::-webkit-scrollbar-thumb:hover {
|
|
background: var(--oc-scrollbar-thumb-hover) !important;
|
|
background-clip: padding-box;
|
|
}
|
|
|
|
[data-scrollbar="chat"].chat-scroll::-webkit-scrollbar-thumb:hover,
|
|
.chat-scroll::-webkit-scrollbar-thumb:hover {
|
|
background: var(--oc-scrollbar-thumb-hover) !important;
|
|
background-clip: padding-box;
|
|
}
|
|
|
|
[data-scrollbar="chat"]::-webkit-scrollbar-corner {
|
|
background: transparent !important;
|
|
}
|
|
|
|
/* Hide native scrollbars for overlay targets (all browsers) */
|
|
.overlay-scrollbar-target {
|
|
scrollbar-width: none !important;
|
|
-ms-overflow-style: none !important;
|
|
}
|
|
|
|
.overlay-scrollbar-target::-webkit-scrollbar {
|
|
width: 0 !important;
|
|
height: 0 !important;
|
|
display: none !important;
|
|
}
|
|
|
|
/* Firefox scrollbar support */
|
|
* {
|
|
scrollbar-width: thin;
|
|
scrollbar-color: var(--oc-scrollbar-thumb) transparent;
|
|
}
|
|
|
|
.scrollbar-hidden {
|
|
scrollbar-width: none !important;
|
|
}
|
|
|
|
.scrollbar-hidden::-webkit-scrollbar {
|
|
width: 0 !important;
|
|
height: 0 !important;
|
|
}
|
|
|
|
.dark * {
|
|
scrollbar-color: oklch(0.6 0.02 80 / 0.3) transparent;
|
|
}
|
|
|
|
/* Overlay scrollbar styling (custom thumb) */
|
|
.overlay-scrollbar {
|
|
position: absolute;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
transition: opacity 0.2s ease;
|
|
z-index: 10;
|
|
}
|
|
|
|
.overlay-scrollbar--dense,
|
|
.overlay-scrollbar--bottom-right,
|
|
.overlay-scrollbar--zero,
|
|
.overlay-scrollbar--flush {
|
|
/* no-op: positioning handled inline */
|
|
}
|
|
|
|
.overlay-scrollbar__thumb {
|
|
pointer-events: auto;
|
|
position: absolute;
|
|
width: 6px;
|
|
background: var(--oc-scrollbar-thumb);
|
|
border-radius: 9999px;
|
|
opacity: 0.8;
|
|
transition: background-color 0.15s ease, opacity 0.15s ease;
|
|
will-change: transform, height;
|
|
}
|
|
|
|
.overlay-scrollbar__thumb:hover,
|
|
.overlay-scrollbar__thumb:active {
|
|
background: var(--oc-scrollbar-thumb-hover);
|
|
opacity: 1;
|
|
}
|
|
|
|
.overlay-scrollbar__thumb--horizontal {
|
|
height: 6px;
|
|
margin: 0;
|
|
}
|
|
|
|
.overlay-scrollbar__thumb--vertical {
|
|
margin: 0;
|
|
}
|
|
|
|
/* Pierre diff viewer styling */
|
|
.pierre-diff-wrapper {
|
|
--diffs-font-family: var(--font-mono, 'IBM Plex Mono', monospace);
|
|
--diffs-font-size: var(--text-code, 13px);
|
|
--diffs-line-height: 1.5;
|
|
--diffs-tab-size: 2;
|
|
--diffs-header-font-family: var(--font-sans, 'IBM Plex Sans', sans-serif);
|
|
--diffs-min-number-column-width: 4ch;
|
|
--diffs-gap-inline: 0;
|
|
--diffs-gap-block: 0;
|
|
}
|
|
|
|
/* Desktop: slightly smaller diff code text */
|
|
:root:not(.mobile-pointer) .pierre-diff-wrapper {
|
|
--diffs-font-size: 0.8125rem;
|
|
}
|
|
|
|
/* WebKit scroll rendering optimizations */
|
|
/* Note: avoid will-change and contain as they break resize behavior */
|
|
.pierre-diff-wrapper,
|
|
.pierre-diff-wrapper diffs-container {
|
|
/* Force GPU compositing layer */
|
|
transform: translateZ(0);
|
|
-webkit-transform: translateZ(0);
|
|
-webkit-backface-visibility: hidden;
|
|
backface-visibility: hidden;
|
|
|
|
/* WebKit touch scroll optimization */
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
.pierre-diff-wrapper diffs-container {
|
|
display: block;
|
|
}
|
|
|
|
/* Header tab responsiveness */
|
|
:root:not(.mobile-pointer):not(.vscode-runtime) .header-tab-label {
|
|
display: inline;
|
|
}
|
|
|
|
@media (max-width: 940px) {
|
|
:root:not(.mobile-pointer):not(.vscode-runtime) .header-tab-label {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
/* ============================================
|
|
Streamdown Styles
|
|
Minimal overrides - fonts only, using Streamdown defaults
|
|
============================================ */
|
|
|
|
/* VS Code webviews can inject default pre/code/blockquote backgrounds; tool input/output should inherit the card surface. */
|
|
.tool-input-surface pre,
|
|
.tool-input-surface code,
|
|
.tool-input-surface blockquote,
|
|
.tool-input-text {
|
|
background: transparent !important;
|
|
background-color: transparent !important;
|
|
}
|
|
|
|
/* VSCode: tool cards should honor semantic code sizing, even when syntax themes inject sizes. */
|
|
:root.vscode-runtime .tool-input-surface,
|
|
:root.vscode-runtime .tool-output-surface {
|
|
font-size: var(--text-code) !important;
|
|
}
|
|
|
|
:root.vscode-runtime .tool-input-surface code,
|
|
:root.vscode-runtime .tool-input-surface pre,
|
|
:root.vscode-runtime .tool-output-surface code,
|
|
:root.vscode-runtime .tool-output-surface pre {
|
|
font-size: inherit !important;
|
|
}
|
|
|
|
/* Model/agent controls: agent label hides before model label. */
|
|
@container model-controls (max-width: 11rem) {
|
|
.model-controls__agent-label {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
@container model-controls (max-width: 9rem) {
|
|
.model-controls__model-label {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
/* VS Code side panel: collapse earlier to save horizontal space. */
|
|
@container model-controls (max-width: 9rem) {
|
|
:root.vscode-runtime .model-controls__agent-label {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
@container model-controls (max-width: 10rem) {
|
|
:root.vscode-runtime .model-controls__model-label {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
/* Commit actions: collapse labels when narrow. */
|
|
@container commit-actions (max-width: 28rem) {
|
|
.commit-actions__label--long {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
@container commit-actions (max-width: 22rem) {
|
|
.commit-actions__label {
|
|
display: none;
|
|
}
|
|
|
|
.commit-actions__btn {
|
|
padding-inline: 0.5rem;
|
|
}
|
|
}
|
|
|
|
/* Text font: IBM Plex Sans */
|
|
.streamdown-content {
|
|
font-family: var(--font-sans);
|
|
font-size: var(--text-markdown);
|
|
}
|
|
|
|
/* Tool markdown should render at code size to match tool card typography. */
|
|
.streamdown-content.streamdown-tool {
|
|
font-size: var(--text-code) !important;
|
|
}
|
|
|
|
.streamdown-content.streamdown-tool code,
|
|
.streamdown-content.streamdown-tool pre {
|
|
font-size: inherit !important;
|
|
}
|
|
|
|
/* Streamdown headers: keep proportional but not oversized */
|
|
.streamdown-content h1 {
|
|
font-size: 1.125em;
|
|
font-weight: 600;
|
|
margin-top: 1em;
|
|
margin-bottom: 0.5em;
|
|
}
|
|
|
|
.streamdown-content h2 {
|
|
font-size: 1.0625em;
|
|
font-weight: 600;
|
|
margin-top: 0.875em;
|
|
margin-bottom: 0.375em;
|
|
}
|
|
|
|
.streamdown-content h3 {
|
|
font-size: 1em;
|
|
font-weight: 600;
|
|
margin-top: 0.75em;
|
|
margin-bottom: 0.25em;
|
|
}
|
|
|
|
.streamdown-content h4,
|
|
.streamdown-content h5,
|
|
.streamdown-content h6 {
|
|
font-size: 1em;
|
|
font-weight: 600;
|
|
margin-top: 0.625em;
|
|
margin-bottom: 0.25em;
|
|
}
|
|
|
|
/* Code font: IBM Plex Mono */
|
|
.streamdown-content code,
|
|
.streamdown-content pre {
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-code);
|
|
}
|
|
|
|
/* Streamdown code blocks: ensure light/dark Shiki vars work even when Tailwind doesn't scan Streamdown's internal class names. */
|
|
.streamdown-content [data-streamdown="code-block-body"] {
|
|
font-size: var(--text-code);
|
|
background-color: var(--shiki-light-bg, transparent);
|
|
color: var(--shiki-light, inherit);
|
|
}
|
|
|
|
.dark .streamdown-content [data-streamdown="code-block-body"] {
|
|
background-color: var(--shiki-dark-bg, var(--shiki-light-bg, transparent));
|
|
color: var(--shiki-dark, var(--shiki-light, inherit));
|
|
}
|
|
|
|
.dark .streamdown-content [data-streamdown="code-block-body"] span[style*="--shiki-dark"] {
|
|
color: var(--shiki-dark) !important;
|
|
}
|
|
|
|
/* Fix list styling - override Tailwind reset */
|
|
.streamdown-content ul {
|
|
list-style-type: disc;
|
|
list-style-position: outside;
|
|
padding-left: 1.5em;
|
|
}
|
|
|
|
.streamdown-content ol {
|
|
list-style-type: decimal;
|
|
list-style-position: outside;
|
|
padding-left: 1.5em;
|
|
}
|
|
|
|
.streamdown-content li {
|
|
display: list-item;
|
|
}
|
|
|
|
/* Reduce code block header height */
|
|
[data-streamdown="code-block-header"] {
|
|
padding: 0.375rem 0.75rem;
|
|
}
|
|
|
|
/* Disable Streamdown's code block virtualization (content-visibility) to avoid late height changes that break scroll-to-bottom. */
|
|
.streamdown-content [data-streamdown="code-block"] {
|
|
content-visibility: visible !important;
|
|
contain-intrinsic-size: none !important;
|
|
}
|
|
|
|
/* Hide system caret in terminal - targets both Ghostty internal input and our custom touch input */
|
|
.terminal-viewport-container textarea {
|
|
caret-color: transparent !important;
|
|
}
|
|
|
|
/* Mobile Terminal Optimizations */
|
|
@media (max-width: 1024px) {
|
|
.terminal-viewport-container {
|
|
font-variant-ligatures: none;
|
|
font-feature-settings: "liga" 0, "calt" 0;
|
|
}
|
|
}
|
|
|
|
/* Font loading states */
|
|
.fonts-loading .terminal-viewport-container {
|
|
font-family: monospace;
|
|
}
|
|
|
|
.fonts-loaded .terminal-viewport-container {
|
|
font-family: "JetBrainsMono Nerd Font", "FiraCode Nerd Font", "Fira Code", "JetBrains Mono", "SFMono-Regular", Menlo, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
}
|
|
|
|
@keyframes grid-pulse {
|
|
0%, 100% {
|
|
opacity: 0.2;
|
|
transform: scale(0.8);
|
|
}
|
|
50% {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
.animate-grid-pulse {
|
|
animation: grid-pulse 1.2s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes marquee-scroll {
|
|
0% { transform: translateX(0); }
|
|
100% { transform: translateX(-100%); }
|
|
}
|
|
|
|
.marquee-text {
|
|
display: inline-block;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.group:hover .marquee-text--active,
|
|
.marquee-text--active:hover {
|
|
animation: marquee-scroll 5s linear infinite alternate;
|
|
}
|