diff --git a/apps/packages/ui/src/pannel-session.tsx b/apps/packages/ui/src/pannel-session.tsx index a9b7034772..b083605753 100644 --- a/apps/packages/ui/src/pannel-session.tsx +++ b/apps/packages/ui/src/pannel-session.tsx @@ -28,7 +28,7 @@ export function SessionPanel({
( function SessionPanelContent({ children, className, wrapperClassName }, ref) { return ( -
+
=0.3.1'} + dockview-core@4.13.1: + resolution: {integrity: sha512-+7vR0ZEoL8CNck6NqDVUMqBT22niwBu5CMMI137dZ3c8NDc7c5Si+3dGEqQgM4lNtHBLAtvypo1C4p21J2wkiQ==} + + dockview-react@4.13.1: + resolution: {integrity: sha512-xnK0mUq+gzME/QyzM5nn+SsQO26AA2qZlCuqi1KX7wux52KIUSMraQHN5AY9Qm2qCVb/NHhCZoZNSysb/GS79A==} + + dockview@4.13.1: + resolution: {integrity: sha512-K8xnYt3Rvkx8MYKHaEsb8aFaPyQclKRRkXS9JcpQPZUgqxumTLnSidgdd6uIfzEps6yJsXoZGQGJ9PtcaKyDcQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -9782,6 +9796,19 @@ snapshots: diff@8.0.3: {} + dockview-core@4.13.1: {} + + dockview-react@4.13.1(react@19.2.3): + dependencies: + dockview: 4.13.1(react@19.2.3) + transitivePeerDependencies: + - react + + dockview@4.13.1(react@19.2.3): + dependencies: + dockview-core: 4.13.1 + react: 19.2.3 + doctrine@2.1.0: dependencies: esutils: 2.0.3 diff --git a/apps/web/app/dockview-theme.css b/apps/web/app/dockview-theme.css new file mode 100644 index 0000000000..208618bc70 --- /dev/null +++ b/apps/web/app/dockview-theme.css @@ -0,0 +1,187 @@ +/* Dockview theme — Mux-inspired pill tabs */ + +.dockview-theme-kandev { + /* Overall dockview bg (visible in gaps between groups) — match card to eliminate visible gaps */ + --dv-background-color: var(--card); + + /* Each group panel area */ + --dv-group-view-background-color: var(--background); + + /* Separator / sash */ + --dv-separator-border: var(--border); + --dv-active-sash-color: var(--primary); + --dv-paneview-header-border-color: var(--border); + + /* Tab bar — #171717 bg, matching panel content */ + --dv-tabs-and-actions-container-font-size: 12px; + --dv-tabs-and-actions-container-background-color: var(--background); + + /* Active group, selected tab — #2a2a2a pill */ + --dv-activegroup-visiblepanel-tab-background-color: var(--muted); + --dv-activegroup-visiblepanel-tab-color: var(--foreground); + + /* Active group, unselected tab — transparent */ + --dv-activegroup-hiddenpanel-tab-background-color: transparent; + --dv-activegroup-hiddenpanel-tab-color: var(--muted-foreground); + + /* Inactive group tabs — more dimmed */ + --dv-inactivegroup-visiblepanel-tab-background-color: color-mix(in srgb, var(--muted) 100%, transparent); + --dv-inactivegroup-visiblepanel-tab-color: color-mix(in srgb, var(--muted-foreground) 100%, transparent); + --dv-inactivegroup-hiddenpanel-tab-background-color: transparent; + --dv-inactivegroup-hiddenpanel-tab-color: color-mix(in srgb, var(--muted-foreground) 100%, transparent); + + /* Close icon */ + --dv-tab-close-icon: var(--muted-foreground); + + /* Misc */ + --dv-tabs-container-scrollbar-color: var(--scrollbar-thumb); + --dv-drag-over-background-color: color-mix(in oklab, var(--primary) 10%, transparent); + --dv-drag-over-border-color: var(--primary); +} + +/* ── Inactive group tab bar dimming ── */ +.dockview-theme-kandev .inactive-group .dv-tabs-and-actions-container { + /* opacity: 0.6; */ +} + +/* ── Tab bar container ── */ +.dockview-theme-kandev .dv-tabs-and-actions-container { + background: var(--background); + border-bottom: 1px solid var(--border); + min-height: 34px; + height: 34px; + padding: 0 6px; + align-items: center; +} + +/* Remove tab divider separators */ +.dockview-theme-kandev .dv-tabs-container.dv-horizontal .dv-tab::before { + display: none !important; +} + +/* ── Individual tabs — pill style ── */ +.dockview-theme-kandev .dv-tab { + padding: 0; + margin: 0 2px; + font-size: 12px; + font-weight: 500; + min-width: auto; + border-radius: 6px; + border-bottom: none !important; + outline: none !important; + transition: background-color 0.15s ease, color 0.15s ease; +} + +.dockview-theme-kandev .dv-tab:hover { + background: color-mix(in srgb, var(--muted) 50%, transparent); + color: var(--foreground); +} + +/* Active tab — filled pill, no underline */ +.dockview-theme-kandev .dv-active-tab { + border-bottom: none !important; +} + +/* ── Default tab (built-in with close button) ── */ +.dockview-theme-kandev .dv-default-tab { + font-size: 12px; + font-weight: 500; + padding: 2px 6px; + gap: 6px; +} + +/* Close button — show on hover and active */ +.dockview-theme-kandev .dv-default-tab .dv-default-tab-action { + opacity: 0; + transition: opacity 0.15s ease; + border-radius: 3px; + padding: 2px; + display: flex; + align-items: center; + justify-content: center; +} + +.dockview-theme-kandev .dv-default-tab .dv-default-tab-action .dv-svg { + height: 8px; + width: 8px; +} + +.dockview-theme-kandev .dv-default-tab .dv-default-tab-action:hover { + background: color-mix(in srgb, var(--foreground) 12%, transparent); +} + +.dockview-theme-kandev .dv-tab:hover .dv-default-tab .dv-default-tab-action, +.dockview-theme-kandev .dv-active-tab .dv-default-tab .dv-default-tab-action { + opacity: 1; +} + +/* ── Panel content ── */ +.dockview-theme-kandev .dv-content-container { + background: var(--card); +} + +/* Strip all chrome from session panel wrappers inside dockview */ +.dockview-theme-kandev .dv-content-container .session-panel-content-wrapper { + border-radius: 0 !important; + box-shadow: none !important; +} + +.dockview-theme-kandev .dv-content-container .session-panel-wrapper { + border: none !important; + border-radius: 0 !important; + padding: 0 !important; + margin: 0 !important; +} + +/* ── Sash (resize handle) ── */ +.dockview-theme-kandev .dv-resize-container > .sash-container .sash { + background: transparent; + transition: background-color 0.15s ease; +} + +.dockview-theme-kandev .dv-resize-container > .sash-container .sash:hover, +.dockview-theme-kandev .dv-resize-container > .sash-container .sash.active { + background: var(--primary); +} + +/* Hide close button on tabs in locked groups (sidebar) */ +.dockview-theme-kandev .dv-locked-groupview .dv-default-tab .dv-default-tab-action { + display: none !important; +} + +/* ── Left header actions (after last tab — "+" button) ── */ +.dockview-theme-kandev .dv-left-actions-container { + display: flex; + align-items: center; + padding-left: 4px; + gap: 2px; +} + +.dv-tab:focus-within:after, .dv-tab:focus:after{ + outline: none !important; +} + +/* ── Right header actions ── */ +.dockview-theme-kandev .dv-right-actions-container { + display: flex; + align-items: center; + padding-right: 4px; + gap: 2px; +} + +/* ── Void container (spacer between left-actions and right-actions) ── */ +.dockview-theme-kandev .dv-void-container { + flex: 1; +} + +/* ── Watermark (empty group) ── */ +.dockview-theme-kandev .dv-watermark { + background: transparent; +} + +/* ── Drop target overlay ── */ +.dockview-theme-kandev .drop-target-dropzone > .drop-target-selection { + border: 2px solid var(--primary); + background: color-mix(in oklab, var(--primary) 8%, transparent); + border-radius: 4px; +} diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css index cdc27e9a3a..54dab4f2b9 100644 --- a/apps/web/app/globals.css +++ b/apps/web/app/globals.css @@ -2,6 +2,8 @@ @import "tw-animate-css"; @import "shadcn/tailwind.css"; @import "@kandev/theme/fonts.css"; +@import "dockview-react/dist/styles/dockview.css"; +@import "./dockview-theme.css"; @source "../components/**/*.{js,ts,jsx,tsx}"; @source "../../packages/ui/src/**/*.{js,ts,jsx,tsx}"; @@ -99,40 +101,41 @@ } .dark { - --background: oklch(0.145 0 0); - --foreground: oklch(0.985 0 0); - --card: oklch(0.205 0 0); - --card-foreground: oklch(0.985 0 0); - --popover: oklch(0.205 0 0); - --popover-foreground: oklch(0.985 0 0); + /* Grey scale: #141414 bg → #1c1c1c card → #2a2a2a borders → #333 hover */ + --background: #141414; + --foreground: #d4d4d4; + --card: #1c1c1c; + --card-foreground: #d4d4d4; + --popover: #222222; + --popover-foreground: #d4d4d4; --primary: oklch(0.59 0.20 277); --primary-foreground: oklch(0.96 0.02 272); - --secondary: oklch(0.274 0.006 286.033); - --secondary-foreground: oklch(0.985 0 0); - --muted: oklch(0.269 0 0); - --muted-foreground: oklch(0.708 0 0); + --secondary: #2a2a2a; + --secondary-foreground: #d4d4d4; + --muted: #2a2a2a; + --muted-foreground: #888888; --accent: oklch(0.62 0.18 276); - --accent-foreground: oklch(0.98 0 0); + --accent-foreground: #d4d4d4; --destructive: oklch(0.704 0.191 22.216); - --border: oklch(1 0 0 / 10%); - --input: oklch(1 0 0 / 15%); - --ring: oklch(0.556 0 0); + --border: #2a2a2a; + --input: #2a2a2a; + --ring: #555555; --chart-1: oklch(0.79 0.10 275); --chart-2: oklch(0.68 0.16 277); --chart-3: oklch(0.59 0.20 277); --chart-4: oklch(0.51 0.23 277); --chart-5: oklch(0.46 0.21 277); - --sidebar: oklch(0.205 0 0); - --sidebar-foreground: oklch(0.985 0 0); + --sidebar: #171717; + --sidebar-foreground: #d4d4d4; --sidebar-primary: oklch(0.68 0.16 277); --sidebar-primary-foreground: oklch(0.96 0.02 272); - --sidebar-accent: oklch(0.269 0 0); - --sidebar-accent-foreground: oklch(0.985 0 0); - --sidebar-border: oklch(1 0 0 / 10%); - --scrollbar-thumb: oklch(0.48 0 0 / 0.7); - --scrollbar-thumb-hover: oklch(0.62 0 0 / 0.8); + --sidebar-accent: #2a2a2a; + --sidebar-accent-foreground: #d4d4d4; + --sidebar-border: #262626; + --scrollbar-thumb: rgba(100, 100, 100, 0.5); + --scrollbar-thumb-hover: rgba(130, 130, 130, 0.6); --scrollbar-track: var(--background); - --sidebar-ring: oklch(0.556 0 0); + --sidebar-ring: #555555; /* Git diff colors - same as light mode for consistency */ --git-addition: 16 185 129; /* emerald-500 */ @@ -172,11 +175,7 @@ background-clip: padding-box; } -/* xterm.js custom scrollbar styling to match global scrollbars */ -.xterm .xterm-scrollable-element { - background: var(--background) !important; -} - +/* xterm.js scrollbar styling */ .xterm .xterm-scrollable-element > .scrollbar { width: 10px !important; right: 0 !important; @@ -338,6 +337,25 @@ animation: shimmer-vertical 1.5s ease-in-out infinite; } +@keyframes chat-input-running { + 0%, 100% { + border-color: color-mix(in oklab, var(--primary) 40%, var(--border)); + box-shadow: + 0 0 6px 1px color-mix(in oklab, var(--primary) 12%, transparent), + 0 0 15px 3px color-mix(in oklab, var(--primary) 6%, transparent); + } + 50% { + border-color: color-mix(in oklab, var(--primary) 70%, var(--border)); + box-shadow: + 0 0 20px 4px color-mix(in oklab, var(--primary) 20%, transparent), + 0 0 50px 8px color-mix(in oklab, var(--primary) 10%, transparent); + } +} + +.chat-input-running { + animation: chat-input-running 3s ease-in-out infinite; +} + @layer components { .border-flash-animation { position: relative; @@ -501,12 +519,11 @@ .milkdown-wrapper { height: 100%; overflow: auto; - background: #000000; /* Black background like chat */ - border-radius: 0.5rem; /* rounded-lg like chat */ + border-radius: 0; } .milkdown-wrapper:not(.dark) { - background: #ffffff; /* White background for light mode */ + background: #ffffff; } .milkdown-wrapper .milkdown { @@ -619,7 +636,7 @@ /* Code blocks */ .milkdown-wrapper .editor pre { - background: #000000 !important; + background: var(--background) !important; padding: 0.5rem 0.75rem !important; border-radius: 0.375rem !important; overflow-x: auto !important; @@ -721,3 +738,7 @@ font-size: 0.75rem; user-select: none; } + +.debug { + border: 1px solid red !important; +} diff --git a/apps/web/components/kanban-board.tsx b/apps/web/components/kanban-board.tsx index bf3751e574..2a87c37535 100644 --- a/apps/web/components/kanban-board.tsx +++ b/apps/web/components/kanban-board.tsx @@ -207,7 +207,7 @@ export function KanbanBoard({ onPreviewTask, onOpenTask }: KanbanBoardProps = {} } return ( -
+
{localValue && !isLoading && ( + + + + + {showIframeDelayed ? ( +