2245 lines
58 KiB
CSS
2245 lines
58 KiB
CSS
@import "tailwindcss";
|
|
@import "tw-animate-css";
|
|
@import "@kandev/theme/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}";
|
|
|
|
@custom-variant dark (&:is(.dark *));
|
|
|
|
@theme inline {
|
|
--color-background: var(--background);
|
|
--color-foreground: var(--foreground);
|
|
--font-sans: var(--font-sans);
|
|
--font-mono:
|
|
"Monaspace Neon", "Geist Mono", "NerdFontLocalGlyphs", "NerdFontBundledGlyphs", ui-monospace,
|
|
SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
--font-mono-size: 12px;
|
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
--color-sidebar-border: var(--sidebar-border);
|
|
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
--color-sidebar-accent: var(--sidebar-accent);
|
|
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
--color-sidebar-primary: var(--sidebar-primary);
|
|
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
--color-sidebar: var(--sidebar);
|
|
--color-chart-5: var(--chart-5);
|
|
--color-chart-4: var(--chart-4);
|
|
--color-chart-3: var(--chart-3);
|
|
--color-chart-2: var(--chart-2);
|
|
--color-chart-1: var(--chart-1);
|
|
--color-ring: var(--ring);
|
|
--color-input: var(--input);
|
|
--color-border: var(--border);
|
|
--color-destructive: var(--destructive);
|
|
--color-destructive-foreground: var(--destructive-foreground);
|
|
--color-success: var(--success);
|
|
--color-success-foreground: var(--success-foreground);
|
|
--color-warning: var(--warning);
|
|
--color-warning-foreground: var(--warning-foreground);
|
|
--color-info: var(--info);
|
|
--color-info-foreground: var(--info-foreground);
|
|
--color-running: var(--running);
|
|
--color-running-foreground: var(--running-foreground);
|
|
--color-pending: var(--pending);
|
|
--color-pending-foreground: var(--pending-foreground);
|
|
--color-remote: var(--remote);
|
|
--color-remote-foreground: var(--remote-foreground);
|
|
--color-archived: var(--archived);
|
|
--color-archived-foreground: var(--archived-foreground);
|
|
--color-accent-foreground: var(--accent-foreground);
|
|
--color-accent: var(--accent);
|
|
--color-muted-foreground: var(--muted-foreground);
|
|
--color-muted: var(--muted);
|
|
--color-secondary-foreground: var(--secondary-foreground);
|
|
--color-secondary: var(--secondary);
|
|
--color-primary-foreground: var(--primary-foreground);
|
|
--color-primary: var(--primary);
|
|
--color-popover-foreground: var(--popover-foreground);
|
|
--color-popover: var(--popover);
|
|
--color-card-foreground: var(--card-foreground);
|
|
--color-card: var(--card);
|
|
--radius-sm: var(--radius);
|
|
--radius-md: var(--radius);
|
|
--radius-lg: var(--radius);
|
|
--radius-xl: var(--radius);
|
|
--radius-2xl: var(--radius);
|
|
--radius-3xl: var(--radius);
|
|
--radius-4xl: var(--radius);
|
|
}
|
|
|
|
:root {
|
|
--app-status-bar-height: 0px;
|
|
--font-geist-sans:
|
|
"Geist", "NerdFontLocalGlyphs", "NerdFontBundledGlyphs", ui-sans-serif, system-ui,
|
|
-apple-system, "Segoe UI", sans-serif;
|
|
--font-sans:
|
|
"Figtree", "Geist", "NerdFontLocalGlyphs", "NerdFontBundledGlyphs", ui-sans-serif, system-ui,
|
|
-apple-system, "Segoe UI", sans-serif;
|
|
--font-geist-mono:
|
|
"Geist Mono", "NerdFontLocalGlyphs", "NerdFontBundledGlyphs", ui-monospace, "SFMono-Regular",
|
|
Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
--background: oklch(1 0 0);
|
|
--foreground: oklch(0.145 0 0);
|
|
--card: oklch(1 0 0);
|
|
--card-foreground: oklch(0.145 0 0);
|
|
--popover: oklch(1 0 0);
|
|
--popover-foreground: oklch(0.145 0 0);
|
|
--primary: oklch(0.51 0.23 277);
|
|
--primary-foreground: oklch(0.96 0.02 272);
|
|
--secondary: oklch(0.967 0.001 286.375);
|
|
--secondary-foreground: oklch(0.21 0.006 285.885);
|
|
--muted: oklch(0.97 0 0);
|
|
--muted-foreground: oklch(0.556 0 0);
|
|
--accent: oklch(0.68 0.18 276);
|
|
--accent-foreground: oklch(0.98 0 0);
|
|
--destructive: oklch(0.58 0.22 27);
|
|
--destructive-foreground: oklch(0.96 0.02 27);
|
|
--success: oklch(0.58 0.12 150);
|
|
--success-foreground: oklch(0.982 0.01 150);
|
|
--warning: oklch(0.7 0.13 78);
|
|
--warning-foreground: oklch(0.23 0.035 72);
|
|
--info: oklch(0.58 0.12 205);
|
|
--info-foreground: oklch(0.982 0.01 205);
|
|
--running: var(--primary);
|
|
--running-foreground: var(--primary-foreground);
|
|
--pending: oklch(0.556 0 0);
|
|
--pending-foreground: oklch(0.985 0 0);
|
|
--remote: oklch(0.57 0.11 185);
|
|
--remote-foreground: oklch(0.982 0.01 185);
|
|
--archived: oklch(0.556 0 0);
|
|
--archived-foreground: oklch(0.985 0 0);
|
|
--border: oklch(0.922 0 0);
|
|
--input: oklch(0.922 0 0);
|
|
--ring: oklch(0.708 0 0);
|
|
--chart-1: oklch(0.79 0.1 275);
|
|
--chart-2: oklch(0.68 0.16 277);
|
|
--chart-3: oklch(0.59 0.2 277);
|
|
--chart-4: oklch(0.51 0.23 277);
|
|
--chart-5: oklch(0.46 0.21 277);
|
|
--radius: 0.375rem;
|
|
--sidebar: oklch(0.985 0 0);
|
|
--sidebar-foreground: oklch(0.145 0 0);
|
|
--sidebar-primary: oklch(0.51 0.23 277);
|
|
--sidebar-primary-foreground: oklch(0.96 0.02 272);
|
|
--sidebar-accent: oklch(0.97 0 0);
|
|
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
--sidebar-border: oklch(0.922 0 0);
|
|
--scrollbar-thumb: oklch(0.78 0 0);
|
|
--scrollbar-thumb-hover: oklch(0.66 0 0);
|
|
--scrollbar-track: var(--background);
|
|
--sidebar-ring: var(--ring);
|
|
|
|
--git-addition: 63 185 80;
|
|
--git-deletion: 244 112 103;
|
|
}
|
|
|
|
:root[data-app-status-bar-visible="true"] {
|
|
--app-status-bar-height: 1.5rem;
|
|
}
|
|
|
|
.dark {
|
|
--background: #181818;
|
|
--foreground: #d4d4d4;
|
|
--card: #1f1f1f;
|
|
--card-foreground: #d4d4d4;
|
|
--popover: #222222;
|
|
--popover-foreground: #d4d4d4;
|
|
--primary: oklch(0.59 0.2 277);
|
|
--primary-foreground: oklch(0.96 0.02 272);
|
|
--secondary: #2a2a2a;
|
|
--secondary-foreground: #d4d4d4;
|
|
--muted: #2a2a2a;
|
|
--muted-foreground: #888888;
|
|
--accent: oklch(0.62 0.18 276);
|
|
--accent-foreground: #d4d4d4;
|
|
--destructive: oklch(0.704 0.191 22.216);
|
|
--destructive-foreground: #d4d4d4;
|
|
--success: oklch(0.68 0.12 150);
|
|
--success-foreground: oklch(0.16 0.025 150);
|
|
--warning: oklch(0.78 0.12 78);
|
|
--warning-foreground: oklch(0.19 0.035 72);
|
|
--info: oklch(0.7 0.11 205);
|
|
--info-foreground: oklch(0.16 0.025 205);
|
|
--running: var(--primary);
|
|
--running-foreground: var(--primary-foreground);
|
|
--pending: oklch(0.708 0 0);
|
|
--pending-foreground: oklch(0.145 0 0);
|
|
--remote: oklch(0.68 0.11 185);
|
|
--remote-foreground: oklch(0.16 0.025 185);
|
|
--archived: oklch(0.708 0 0);
|
|
--archived-foreground: oklch(0.145 0 0);
|
|
--border: #2a2a2a;
|
|
--input: #2a2a2a;
|
|
--ring: #555555;
|
|
--chart-1: oklch(0.79 0.1 275);
|
|
--chart-2: oklch(0.68 0.16 277);
|
|
--chart-3: oklch(0.59 0.2 277);
|
|
--chart-4: oklch(0.51 0.23 277);
|
|
--chart-5: oklch(0.46 0.21 277);
|
|
--sidebar: #171717;
|
|
--sidebar-foreground: #d4d4d4;
|
|
--sidebar-primary: oklch(0.68 0.16 277);
|
|
--sidebar-primary-foreground: oklch(0.96 0.02 272);
|
|
--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: var(--ring);
|
|
|
|
--git-addition: 63 185 80;
|
|
--git-deletion: 244 112 103;
|
|
}
|
|
|
|
@layer base {
|
|
* {
|
|
@apply border-border outline-ring/50;
|
|
scrollbar-width: thin;
|
|
scrollbar-color: var(--scrollbar-thumb) transparent;
|
|
}
|
|
/* App shell: lock the document to the viewport; each route owns its scroll container. */
|
|
html,
|
|
body {
|
|
@apply h-full overflow-hidden overscroll-none;
|
|
}
|
|
body {
|
|
@apply bg-background text-foreground;
|
|
}
|
|
}
|
|
|
|
@layer components {
|
|
[data-settings-target-highlight="true"] {
|
|
animation: settings-target-highlight 1400ms ease-out;
|
|
}
|
|
|
|
.task-sidebar-row-reveal {
|
|
animation: task-sidebar-row-reveal 1400ms ease-out;
|
|
}
|
|
|
|
[data-settings-dirty="true"] {
|
|
border-color: color-mix(in oklab, var(--success) 65%, var(--border)) !important;
|
|
}
|
|
|
|
[data-settings-dirty="true"]:not(:focus-visible) {
|
|
@apply ring-1 ring-success/15;
|
|
}
|
|
|
|
[data-settings-dirty="true"][data-settings-dirty-level="container"] {
|
|
@apply ring-0;
|
|
border-color: color-mix(in oklab, var(--success) 45%, var(--border)) !important;
|
|
}
|
|
|
|
[data-slot="card"]:has([data-settings-dirty="true"]),
|
|
[data-settings-dirty="true"][data-settings-dirty-level="card"] {
|
|
@apply ring-0;
|
|
border-color: color-mix(in oklab, var(--success) 35%, var(--border)) !important;
|
|
}
|
|
|
|
[data-quick-chat-silent-focus="true"]:focus-visible {
|
|
outline: none !important;
|
|
box-shadow: none !important;
|
|
border-color: transparent !important;
|
|
}
|
|
|
|
[data-workflow-replay-cycle="true"] {
|
|
@apply ring-1 ring-warning/20;
|
|
border-color: color-mix(in oklab, var(--warning) 65%, var(--border)) !important;
|
|
}
|
|
}
|
|
|
|
@keyframes settings-target-highlight {
|
|
0%,
|
|
35% {
|
|
background-color: color-mix(in oklab, var(--primary) 10%, transparent);
|
|
box-shadow: inset 0 0 0 2px color-mix(in oklab, var(--primary) 55%, transparent);
|
|
}
|
|
100% {
|
|
background-color: transparent;
|
|
box-shadow: inset 0 0 0 2px transparent;
|
|
}
|
|
}
|
|
|
|
@keyframes task-sidebar-row-reveal {
|
|
0%,
|
|
35% {
|
|
background-color: color-mix(in oklab, var(--primary) 28%, transparent);
|
|
box-shadow: inset 0 0 0 2px color-mix(in oklab, var(--primary) 55%, transparent);
|
|
}
|
|
100% {
|
|
background-color: transparent;
|
|
box-shadow: inset 0 0 0 2px transparent;
|
|
}
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
[data-settings-target-highlight="true"] {
|
|
animation: none;
|
|
background-color: color-mix(in oklab, var(--primary) 10%, transparent);
|
|
box-shadow: inset 0 0 0 2px color-mix(in oklab, var(--primary) 55%, transparent);
|
|
}
|
|
|
|
.task-sidebar-row-reveal {
|
|
animation: none;
|
|
background-color: color-mix(in oklab, var(--primary) 28%, transparent);
|
|
box-shadow: inset 0 0 0 2px color-mix(in oklab, var(--primary) 55%, transparent);
|
|
}
|
|
}
|
|
|
|
/* WebKit can leave a fixed dialog's transform animation on a separate layer,
|
|
which makes the Create Task surface look soft or briefly sit below its
|
|
overlay. Keep the workaround scoped to the dialog opt-in and the engine
|
|
marker so Chromium keeps the existing motion and geometry. The task's own
|
|
overlay is one level lower so a nested confirmation can reuse the shared
|
|
modal level and still paint above the task form. */
|
|
@keyframes kandev-dialog-webkit-enter {
|
|
from {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes kandev-dialog-webkit-exit {
|
|
to {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
html[data-rendering-engine="webkit"] [data-webkit-safe-motion="true"] {
|
|
inset: 0;
|
|
margin: auto;
|
|
translate: 0 0;
|
|
z-index: 50;
|
|
}
|
|
|
|
html[data-rendering-engine="webkit"] .create-task-dialog-overlay {
|
|
z-index: 49;
|
|
}
|
|
|
|
html[data-rendering-engine="webkit"] .discard-confirmation-overlay {
|
|
z-index: 52;
|
|
}
|
|
|
|
html[data-rendering-engine="webkit"] [data-webkit-modal-layer="discard-confirmation"] {
|
|
z-index: 53;
|
|
height: fit-content;
|
|
}
|
|
|
|
html[data-rendering-engine="webkit"] [data-webkit-safe-motion="true"][data-state="open"] {
|
|
animation-name: kandev-dialog-webkit-enter;
|
|
}
|
|
|
|
html[data-rendering-engine="webkit"] [data-webkit-safe-motion="true"][data-state="closed"] {
|
|
animation-name: kandev-dialog-webkit-exit;
|
|
}
|
|
|
|
/*
|
|
* Tooltip content is `pointer-events: none` (@kandev/ui/tooltip.tsx) so a
|
|
* bubble never blocks clicks on whatever it's covering — but that class only
|
|
* reaches the inner content, not Radix Popper's auto-generated positioning
|
|
* wrapper around it, which keeps the browser default `pointer-events: auto`.
|
|
* A tooltip anchored deep inside a scrollable/nested surface (e.g. an
|
|
* automation help icon inside the MR hover popover) can end up geometrically
|
|
* overlapping unrelated interactive elements above it; without this, that
|
|
* wrapper silently intercepts clicks meant for whatever sits underneath,
|
|
* even after the tooltip's own trigger is no longer hovered.
|
|
*/
|
|
[data-radix-popper-content-wrapper]:has(> [data-slot="tooltip-content"]) {
|
|
pointer-events: none;
|
|
}
|
|
|
|
@media (min-width: 640px) {
|
|
html[data-rendering-engine="webkit"] [data-webkit-safe-motion="true"] {
|
|
height: fit-content;
|
|
}
|
|
}
|
|
|
|
/* iOS Safari auto-zooms a focused form control whose computed font-size is
|
|
< 16px (native <select> included). Force 16px on coarse-pointer (touch)
|
|
devices to stop focus-zoom. !important because some controls are styled by
|
|
more specific selectors that would otherwise win on specificity — e.g. the
|
|
compact `.tiptap pre .code-block-language` picker (0.625rem). Bumping that
|
|
picker to 16px only happens on touch, where a larger tap target is an
|
|
improvement; desktop (fine pointer) keeps the compact size. Only true
|
|
editing hosts get the contenteditable rule — `[contenteditable="false"]`
|
|
decorations (mention chips, code-block views) are excluded.
|
|
`any-pointer` (not `pointer`) so the floor also applies on hybrid devices
|
|
whose primary pointer is fine (e.g. a touchscreen laptop with a mouse),
|
|
where a touch tap can still focus a field. */
|
|
@media (any-pointer: coarse) {
|
|
input,
|
|
textarea,
|
|
select,
|
|
[contenteditable="true"],
|
|
[contenteditable="plaintext-only"] {
|
|
font-size: 16px !important;
|
|
}
|
|
}
|
|
|
|
/* Radix menus are poppers: their inline transform lives on a generated wrapper,
|
|
not the menu surface. On mobile viewports, pin that wrapper to the
|
|
viewport and let the menu scroll internally like a compact bottom sheet. */
|
|
@media (max-width: 639px) {
|
|
.mobile-task-actions {
|
|
display: flex !important;
|
|
opacity: 1 !important;
|
|
pointer-events: auto !important;
|
|
}
|
|
|
|
.mobile-task-actions-button {
|
|
width: 44px;
|
|
height: 44px;
|
|
}
|
|
|
|
.mobile-task-actions-with-stats {
|
|
gap: 0.125rem;
|
|
}
|
|
|
|
.mobile-task-actions-slot {
|
|
position: static;
|
|
}
|
|
|
|
.mobile-task-diff-stats {
|
|
opacity: 1 !important;
|
|
}
|
|
|
|
[data-radix-popper-content-wrapper]:has(
|
|
> :is(
|
|
[data-slot="context-menu-content"],
|
|
[data-slot="context-menu-sub-content"],
|
|
[data-slot="dropdown-menu-content"],
|
|
[data-slot="dropdown-menu-sub-content"]
|
|
)
|
|
) {
|
|
position: fixed !important;
|
|
inset: auto 8px max(8px, env(safe-area-inset-bottom, 0px)) 8px !important;
|
|
width: auto !important;
|
|
min-width: 0 !important;
|
|
transform: none !important;
|
|
will-change: auto !important;
|
|
}
|
|
|
|
/* The root positioner owns one backdrop outside the scrolling menu.
|
|
Submenus keep that layer, and Radix retains outside-interaction handling. */
|
|
[data-radix-popper-content-wrapper]:has(> .mobile-menu-root)::before {
|
|
@apply bg-black/80 supports-backdrop-filter:backdrop-blur-xs;
|
|
content: "";
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: -1;
|
|
pointer-events: none;
|
|
opacity: 0;
|
|
transition: opacity 100ms;
|
|
}
|
|
|
|
[data-radix-popper-content-wrapper]:has(> .mobile-menu-root[data-state="open"])::before {
|
|
opacity: 1;
|
|
}
|
|
|
|
:is(
|
|
[data-slot="context-menu-content"],
|
|
[data-slot="context-menu-sub-content"],
|
|
[data-slot="dropdown-menu-content"],
|
|
[data-slot="dropdown-menu-sub-content"]
|
|
) {
|
|
width: 100% !important;
|
|
min-width: 0 !important;
|
|
max-width: none !important;
|
|
max-height: min(70dvh, calc(100dvh - 16px - env(safe-area-inset-bottom, 0px))) !important;
|
|
padding: 0.5rem !important;
|
|
border-radius: 1rem !important;
|
|
overflow-x: hidden !important;
|
|
overflow-y: auto !important;
|
|
overscroll-behavior: contain;
|
|
-webkit-overflow-scrolling: touch;
|
|
transform-origin: bottom center !important;
|
|
}
|
|
|
|
:is(
|
|
[data-slot="context-menu-item"],
|
|
[data-slot="context-menu-checkbox-item"],
|
|
[data-slot="context-menu-radio-item"],
|
|
[data-slot="context-menu-sub-trigger"],
|
|
[data-slot="dropdown-menu-item"],
|
|
[data-slot="dropdown-menu-checkbox-item"],
|
|
[data-slot="dropdown-menu-radio-item"],
|
|
[data-slot="dropdown-menu-sub-trigger"]
|
|
) {
|
|
min-height: 44px;
|
|
padding-block: 0.625rem;
|
|
font-size: 0.875rem;
|
|
line-height: 1.25rem;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
*::-webkit-scrollbar {
|
|
width: 10px;
|
|
height: 10px;
|
|
}
|
|
|
|
*::-webkit-scrollbar-track {
|
|
background: var(--scrollbar-track);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
*::-webkit-scrollbar-thumb {
|
|
background: var(--scrollbar-thumb);
|
|
border-radius: 8px;
|
|
border: 2px solid transparent;
|
|
background-clip: padding-box;
|
|
}
|
|
|
|
*::-webkit-scrollbar-thumb:hover {
|
|
background: var(--scrollbar-thumb-hover);
|
|
background-clip: padding-box;
|
|
}
|
|
|
|
.kanban-scroll-region {
|
|
scrollbar-gutter: stable;
|
|
scrollbar-color: transparent transparent;
|
|
transition: scrollbar-color 120ms ease;
|
|
}
|
|
|
|
.kanban-scroll-region[data-kanban-scroll-axis="horizontal"] {
|
|
scrollbar-gutter: auto;
|
|
}
|
|
|
|
.kanban-scroll-region::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
|
|
.kanban-scroll-region::-webkit-scrollbar-thumb {
|
|
background: transparent;
|
|
background-clip: padding-box;
|
|
}
|
|
|
|
.kanban-scroll-region:is(:hover, :focus-within),
|
|
.kanban-scroll-region[data-kanban-scroll-active="true"] {
|
|
scrollbar-color: var(--scrollbar-thumb) transparent;
|
|
}
|
|
|
|
.kanban-scroll-region:is(:hover, :focus-within)::-webkit-scrollbar-thumb,
|
|
.kanban-scroll-region[data-kanban-scroll-active="true"]::-webkit-scrollbar-thumb {
|
|
background: var(--scrollbar-thumb);
|
|
background-clip: padding-box;
|
|
}
|
|
|
|
.kanban-overflow-fade {
|
|
position: absolute;
|
|
z-index: 1;
|
|
pointer-events: none;
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
transition: opacity 120ms ease;
|
|
}
|
|
|
|
.kanban-overflow-fade-visible {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
}
|
|
|
|
.kanban-overflow-fade-top,
|
|
.kanban-overflow-fade-bottom {
|
|
right: 10px;
|
|
left: 0;
|
|
height: 48px;
|
|
display: flex;
|
|
justify-content: center;
|
|
padding-block: 4px;
|
|
}
|
|
|
|
.kanban-overflow-chevron {
|
|
color: var(--foreground);
|
|
opacity: 0.75;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.kanban-overflow-fade-top {
|
|
top: 0;
|
|
align-items: flex-start;
|
|
background: linear-gradient(to bottom, var(--background) 25%, transparent);
|
|
}
|
|
|
|
.kanban-overflow-fade-bottom {
|
|
bottom: 0;
|
|
align-items: flex-end;
|
|
background: linear-gradient(to top, var(--background) 25%, transparent);
|
|
}
|
|
|
|
.kanban-overflow-fade-left,
|
|
.kanban-overflow-fade-right {
|
|
top: 0;
|
|
bottom: 10px;
|
|
width: 16px;
|
|
}
|
|
|
|
.kanban-overflow-fade-left {
|
|
left: 0;
|
|
background: linear-gradient(to right, var(--background), transparent);
|
|
}
|
|
|
|
.kanban-overflow-fade-right {
|
|
right: 0;
|
|
background: linear-gradient(to left, var(--background), transparent);
|
|
}
|
|
|
|
@media (any-pointer: coarse) {
|
|
.kanban-scroll-region {
|
|
scrollbar-color: var(--scrollbar-thumb) transparent;
|
|
}
|
|
|
|
.kanban-scroll-region::-webkit-scrollbar-thumb {
|
|
background: var(--scrollbar-thumb);
|
|
background-clip: padding-box;
|
|
}
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.kanban-scroll-region,
|
|
.kanban-overflow-fade {
|
|
transition: none;
|
|
}
|
|
}
|
|
|
|
@media (forced-colors: active) {
|
|
.kanban-scroll-region {
|
|
scrollbar-color: auto;
|
|
transition: none;
|
|
}
|
|
|
|
.kanban-scroll-region::-webkit-scrollbar-thumb {
|
|
background: ButtonText;
|
|
}
|
|
|
|
.kanban-overflow-fade {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.task-sidebar-scroll[data-can-scroll-down="true"] {
|
|
mask-image: linear-gradient(to bottom, black 0, black calc(100% - 3.5rem), transparent 100%);
|
|
-webkit-mask-image: linear-gradient(
|
|
to bottom,
|
|
black 0,
|
|
black calc(100% - 3.5rem),
|
|
transparent 100%
|
|
);
|
|
}
|
|
|
|
.task-sidebar-scroll-root [data-slot="scroll-area-scrollbar"] {
|
|
z-index: 1;
|
|
background: transparent;
|
|
}
|
|
|
|
.task-sidebar-scroll-root [data-slot="scroll-area-thumb"] {
|
|
background: var(--scrollbar-thumb);
|
|
}
|
|
|
|
.task-sidebar-scroll-root [data-slot="scroll-area-thumb"]:hover {
|
|
background: var(--scrollbar-thumb-hover);
|
|
}
|
|
|
|
@media (hover: hover) and (pointer: fine) {
|
|
.task-sidebar-scroll-root [data-slot="scroll-area-scrollbar"] {
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transition: opacity 120ms ease;
|
|
}
|
|
|
|
.task-sidebar-scroll-root:is(:hover, :focus-within) .task-sidebar-scroll {
|
|
mask-image: none;
|
|
-webkit-mask-image: none;
|
|
}
|
|
|
|
.task-sidebar-scroll-root:is(:hover, :focus-within) [data-slot="scroll-area-scrollbar"] {
|
|
opacity: 1;
|
|
pointer-events: auto;
|
|
}
|
|
}
|
|
|
|
/* xterm.js scrollbar styling */
|
|
.xterm .xterm-scrollable-element > .scrollbar {
|
|
width: 10px !important;
|
|
right: 0 !important;
|
|
background: transparent !important;
|
|
}
|
|
|
|
.xterm .xterm-scrollable-element > .scrollbar > .slider {
|
|
background: var(--scrollbar-thumb) !important;
|
|
border-radius: 8px !important;
|
|
width: 6px !important;
|
|
left: 2px !important;
|
|
}
|
|
|
|
.xterm .xterm-scrollable-element > .scrollbar:hover > .slider {
|
|
background: var(--scrollbar-thumb-hover) !important;
|
|
}
|
|
|
|
@layer utilities {
|
|
.overflow-wrap-anywhere {
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.scrollbar-hide {
|
|
-ms-overflow-style: none;
|
|
scrollbar-width: none;
|
|
}
|
|
|
|
.scrollbar-hide::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
/* Thin scrollbar for menus */
|
|
.scrollbar-thin {
|
|
scrollbar-width: thin;
|
|
scrollbar-color: var(--scrollbar-thumb) transparent;
|
|
}
|
|
|
|
.scrollbar-thin::-webkit-scrollbar {
|
|
width: 8px;
|
|
}
|
|
|
|
.scrollbar-thin::-webkit-scrollbar-track {
|
|
background: transparent !important;
|
|
}
|
|
|
|
.scrollbar-thin::-webkit-scrollbar-thumb {
|
|
background: var(--scrollbar-thumb);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.scrollbar-thin::-webkit-scrollbar-thumb:hover {
|
|
background: var(--scrollbar-thumb-hover);
|
|
}
|
|
|
|
/* Safe area padding for iPhone notch and home indicator */
|
|
.pb-safe {
|
|
padding-bottom: env(safe-area-inset-bottom, 0px);
|
|
}
|
|
|
|
.pt-safe {
|
|
padding-top: env(safe-area-inset-top, 0px);
|
|
}
|
|
|
|
.pl-safe {
|
|
padding-left: env(safe-area-inset-left, 0px);
|
|
}
|
|
|
|
.pr-safe {
|
|
padding-right: env(safe-area-inset-right, 0px);
|
|
}
|
|
|
|
/* Safe area height for spacer elements */
|
|
.h-safe {
|
|
height: env(safe-area-inset-bottom, 0px);
|
|
}
|
|
}
|
|
|
|
/* Grid Spinner - 3x3 cube animation */
|
|
@keyframes spinner-grid {
|
|
0%,
|
|
70%,
|
|
100% {
|
|
transform: scale3d(0.5, 0.5, 1);
|
|
}
|
|
35% {
|
|
transform: scale3d(0, 0, 1);
|
|
}
|
|
}
|
|
|
|
.spinner-grid {
|
|
display: inline-grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 0.15em;
|
|
width: 1em;
|
|
height: 1em;
|
|
}
|
|
|
|
.spinner-grid-cube {
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: currentColor;
|
|
animation: spinner-grid 1.3s ease-in-out infinite;
|
|
}
|
|
|
|
.spinner-grid-cube:nth-child(1) {
|
|
animation-delay: 0.2s;
|
|
}
|
|
.spinner-grid-cube:nth-child(2) {
|
|
animation-delay: 0.3s;
|
|
}
|
|
.spinner-grid-cube:nth-child(3) {
|
|
animation-delay: 0.4s;
|
|
}
|
|
.spinner-grid-cube:nth-child(4) {
|
|
animation-delay: 0.1s;
|
|
}
|
|
.spinner-grid-cube:nth-child(5) {
|
|
animation-delay: 0.2s;
|
|
}
|
|
.spinner-grid-cube:nth-child(6) {
|
|
animation-delay: 0.3s;
|
|
}
|
|
.spinner-grid-cube:nth-child(7) {
|
|
animation-delay: 0s;
|
|
}
|
|
.spinner-grid-cube:nth-child(8) {
|
|
animation-delay: 0.1s;
|
|
}
|
|
.spinner-grid-cube:nth-child(9) {
|
|
animation-delay: 0.2s;
|
|
}
|
|
|
|
@keyframes border-flash-glow {
|
|
0%,
|
|
100% {
|
|
opacity: 0.35;
|
|
}
|
|
50% {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes shimmer {
|
|
0% {
|
|
transform: translateX(-100%);
|
|
}
|
|
100% {
|
|
transform: translateX(100%);
|
|
}
|
|
}
|
|
|
|
@keyframes shimmer-vertical {
|
|
0% {
|
|
transform: translateY(-100%);
|
|
}
|
|
100% {
|
|
transform: translateY(100%);
|
|
}
|
|
}
|
|
|
|
.animate-shimmer {
|
|
animation: shimmer 1.5s ease-in-out infinite;
|
|
}
|
|
|
|
.animate-shimmer-vertical {
|
|
animation: shimmer-vertical 1.5s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes changes-tab-flash {
|
|
0% {
|
|
background-color: transparent;
|
|
}
|
|
25% {
|
|
background-color: color-mix(in oklab, var(--primary) 25%, transparent);
|
|
}
|
|
100% {
|
|
background-color: transparent;
|
|
}
|
|
}
|
|
|
|
.animate-changes-flash {
|
|
animation: changes-tab-flash 1s ease-out;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* Chat-input "running" affordance.
|
|
*
|
|
* The colored border is a static border-color (painted once). The pulsing glow
|
|
* lives on an absolute HTML target that animates only `opacity`. The target is
|
|
* a child of the OUTER `.relative` wrapper because the inner input box has
|
|
* `overflow-hidden`, which would clip its outer box-shadow. */
|
|
.chat-input-running,
|
|
.chat-input-running-plan {
|
|
border-color: color-mix(in oklab, var(--primary) 55%, var(--border));
|
|
}
|
|
|
|
.chat-input-starting {
|
|
border-color: color-mix(in oklab, var(--primary) 50%, var(--border));
|
|
}
|
|
|
|
@keyframes chat-input-glow-pulse {
|
|
0%,
|
|
100% {
|
|
opacity: 0.4;
|
|
}
|
|
50% {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.chat-input-glow-running,
|
|
.chat-input-glow-starting {
|
|
position: absolute;
|
|
inset: 0;
|
|
border-radius: 0.25rem;
|
|
pointer-events: none;
|
|
z-index: -1;
|
|
animation: chat-input-glow-pulse 3s ease-in-out infinite;
|
|
}
|
|
|
|
.chat-input-glow-running {
|
|
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-glow-starting {
|
|
box-shadow:
|
|
0 0 12px 3px color-mix(in oklab, var(--primary) 15%, transparent),
|
|
0 0 30px 6px color-mix(in oklab, var(--primary) 8%, transparent);
|
|
animation-duration: 2s;
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.animate-changes-flash,
|
|
.chat-input-glow-running,
|
|
.chat-input-glow-starting,
|
|
.border-flash-animation::after,
|
|
.node-border-running::after,
|
|
.search-flash,
|
|
.review-finding-flash,
|
|
.animate-queue-open,
|
|
.animate-queue-close {
|
|
animation: none;
|
|
}
|
|
}
|
|
|
|
@layer components {
|
|
.border-flash-animation {
|
|
position: relative;
|
|
}
|
|
|
|
.border-flash-animation::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
border-radius: inherit;
|
|
pointer-events: none;
|
|
z-index: 10;
|
|
box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--primary) 60%, transparent);
|
|
animation: border-flash-glow 3s ease-in-out infinite;
|
|
}
|
|
}
|
|
|
|
.cm-tooltip {
|
|
border: 1px solid var(--border) !important;
|
|
background: var(--popover, oklch(0.205 0 0)) !important;
|
|
color: var(--popover-foreground, oklch(0.91 0.014 230)) !important;
|
|
border-radius: calc(var(--radius) + 2px);
|
|
box-shadow: 0 12px 32px color-mix(in oklab, var(--foreground) 18%, transparent);
|
|
padding: 8px;
|
|
}
|
|
|
|
.cm-tooltip-autocomplete {
|
|
padding: 0;
|
|
background: var(--popover, oklch(0.205 0 0)) !important;
|
|
}
|
|
|
|
.cm-tooltip-autocomplete ul {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 12px;
|
|
max-height: 240px;
|
|
overflow: auto;
|
|
}
|
|
|
|
.cm-tooltip-autocomplete li {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 10px 12px;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
font-size: 0.875rem;
|
|
color: var(--popover-foreground, oklch(0.91 0.014 230));
|
|
}
|
|
|
|
.cm-tooltip-autocomplete li[aria-selected="true"] {
|
|
background: color-mix(in oklab, var(--primary) 20%, var(--popover)) !important;
|
|
color: var(--primary-foreground) !important;
|
|
border-radius: 0;
|
|
}
|
|
|
|
.cm-tooltip-autocomplete li[aria-selected="true"]:first-child {
|
|
border-top-left-radius: 6px;
|
|
border-top-right-radius: 6px;
|
|
}
|
|
|
|
.cm-tooltip-autocomplete li[aria-selected="true"]:last-child {
|
|
border-bottom-left-radius: 6px;
|
|
border-bottom-right-radius: 6px;
|
|
}
|
|
|
|
.cm-completionLabel {
|
|
font-weight: 500;
|
|
}
|
|
|
|
.cm-completionDetail {
|
|
margin-left: auto;
|
|
font-size: 0.875rem;
|
|
color: var(--muted-foreground) !important;
|
|
}
|
|
|
|
.cm-completionMatchedText {
|
|
text-decoration: none;
|
|
color: var(--primary) !important;
|
|
}
|
|
|
|
.cm-tooltip-autocomplete li[aria-selected="true"] .cm-completionMatchedText {
|
|
color: var(--primary-foreground);
|
|
}
|
|
|
|
.cm-completionIcon {
|
|
opacity: 0.65;
|
|
}
|
|
|
|
.cm-completionIcon {
|
|
width: 14px;
|
|
height: 14px;
|
|
display: inline-block;
|
|
margin-right: 6px;
|
|
color: var(--muted-foreground);
|
|
background-color: currentColor;
|
|
mask-size: contain;
|
|
mask-repeat: no-repeat;
|
|
mask-position: center;
|
|
-webkit-mask-size: contain;
|
|
-webkit-mask-repeat: no-repeat;
|
|
-webkit-mask-position: center;
|
|
}
|
|
|
|
.cm-completionIcon-slash {
|
|
mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M7 9a2 2 0 1 1 2 -2v10a2 2 0 1 1 -2 -2h10a2 2 0 1 1 -2 2v-10a2 2 0 1 1 2 2h-10'/></svg>");
|
|
-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M7 9a2 2 0 1 1 2 -2v10a2 2 0 1 1 -2 -2h10a2 2 0 1 1 -2 2v-10a2 2 0 1 1 2 2h-10'/></svg>");
|
|
}
|
|
|
|
.cm-completionIcon-mention {
|
|
mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M8 12a4 4 0 1 0 8 0a4 4 0 1 0 -8 0'/><path d='M16 12v1.5a2.5 2.5 0 0 0 5 0v-1.5a9 9 0 1 0 -5.5 8.28'/></svg>");
|
|
-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M8 12a4 4 0 1 0 8 0a4 4 0 1 0 -8 0'/><path d='M16 12v1.5a2.5 2.5 0 0 0 5 0v-1.5a9 9 0 1 0 -5.5 8.28'/></svg>");
|
|
}
|
|
|
|
.cm-completionIcon-prompt {
|
|
display: none !important;
|
|
width: 0 !important;
|
|
margin-right: 0 !important;
|
|
background: none !important;
|
|
}
|
|
|
|
.cm-tooltip-autocomplete li[aria-selected="true"] .cm-completionIcon {
|
|
color: var(--primary-foreground);
|
|
}
|
|
|
|
.task-chat-editor .cm-placeholder {
|
|
color: var(--muted-foreground) !important;
|
|
}
|
|
|
|
.task-chat-editor .cm-editor {
|
|
background: transparent !important;
|
|
box-shadow: none !important;
|
|
outline: none !important;
|
|
}
|
|
|
|
.task-chat-editor .cm-editor.cm-focused {
|
|
outline: none !important;
|
|
}
|
|
|
|
.task-chat-editor .cm-scroller,
|
|
.task-chat-editor .cm-content,
|
|
.task-chat-editor .cm-line,
|
|
.task-chat-editor .cm-line span {
|
|
background: transparent !important;
|
|
background-color: transparent !important;
|
|
color: var(--foreground) !important;
|
|
}
|
|
|
|
.task-chat-editor .cm-cursor {
|
|
border-left-color: var(--foreground);
|
|
}
|
|
|
|
.task-chat-editor .cm-selectionBackground {
|
|
background: color-mix(in oklab, var(--primary) 25%, var(--background)) !important;
|
|
}
|
|
|
|
.task-chat-editor .cm-content ::selection {
|
|
background: color-mix(in oklab, var(--primary) 30%, var(--background));
|
|
}
|
|
|
|
/* Legacy Milkdown styles removed - plan editor now uses TipTap */
|
|
|
|
/* Shared markdown body styles
|
|
Single source of truth for rendered markdown across TipTap (plan editor)
|
|
and ReactMarkdown (chat, PR, changelog, etc.). */
|
|
.markdown-body {
|
|
font-size: 13px;
|
|
line-height: 1.625;
|
|
color: var(--foreground);
|
|
overflow-wrap: anywhere;
|
|
font-family:
|
|
-apple-system, "system-ui", "Segoe UI", "Noto Sans", Helvetica, Arial, "NerdFontLocalGlyphs",
|
|
"NerdFontBundledGlyphs", sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
|
}
|
|
|
|
.markdown-body h1,
|
|
.markdown-body h2,
|
|
.markdown-body h3,
|
|
.markdown-body h4,
|
|
.markdown-body h5 {
|
|
font-weight: 700;
|
|
color: var(--foreground);
|
|
margin-top: 1.25rem;
|
|
margin-bottom: 0.375rem;
|
|
line-height: 1.3;
|
|
}
|
|
|
|
.markdown-body :is(h1, h2, h3, h4, h5):first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.markdown-body h1 {
|
|
font-size: 1.25rem;
|
|
}
|
|
|
|
.markdown-body h2 {
|
|
font-size: 1.0625rem;
|
|
}
|
|
|
|
.markdown-body h3 {
|
|
font-size: 0.9375rem;
|
|
}
|
|
|
|
.markdown-body p {
|
|
line-height: 1.625;
|
|
}
|
|
|
|
.markdown-body p + p {
|
|
margin-top: 0.5em;
|
|
}
|
|
|
|
.katex-display {
|
|
max-width: 100%;
|
|
margin: 1em 0;
|
|
overflow-x: auto;
|
|
overflow-y: hidden;
|
|
padding: 0.125rem 0.25rem;
|
|
text-align: left;
|
|
}
|
|
|
|
.katex-display > .katex {
|
|
display: inline-block;
|
|
min-width: max-content;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .ProseMirror::after {
|
|
content: "";
|
|
display: block;
|
|
/* The outer EditorContent owns scrolling, so the spacer extends its range. */
|
|
height: var(--plan-toolbar-clearance, 0px);
|
|
}
|
|
|
|
.markdown-body pre {
|
|
white-space: pre-wrap;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.markdown-body ul {
|
|
list-style-type: disc;
|
|
padding-left: 1.25rem;
|
|
margin-top: 1rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.markdown-body ol {
|
|
list-style-type: decimal;
|
|
padding-left: 1.25rem;
|
|
margin-top: 1rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.markdown-body li {
|
|
margin-top: 0.125rem;
|
|
margin-bottom: 0.125rem;
|
|
}
|
|
|
|
.markdown-body li > ul,
|
|
.markdown-body li > ol {
|
|
margin-top: 0.25rem;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
/* Inline code: neutral foreground on a slightly elevated background with a
|
|
subtle border so chips read clearly against the card surface.
|
|
Linked code (a > code) drops the background and inherits the link
|
|
color so file references read as links, not as another code chip. */
|
|
.markdown-body :not(pre) > code,
|
|
.markdown-body code:not(pre code) {
|
|
background: color-mix(in oklch, var(--foreground) 10%, var(--muted));
|
|
border: 1px solid color-mix(in oklch, var(--foreground) 10%, transparent);
|
|
color: var(--foreground);
|
|
padding: 0.1rem 0.375rem;
|
|
border-radius: 0.25rem;
|
|
font-size: 0.9em;
|
|
font-family: var(--font-mono);
|
|
}
|
|
|
|
.markdown-body a {
|
|
color: var(--primary);
|
|
text-decoration-line: underline;
|
|
text-underline-offset: 2px;
|
|
}
|
|
|
|
.markdown-body a:hover {
|
|
text-decoration-line: underline;
|
|
}
|
|
|
|
/* Code wrapped in a link reads as a link: no fill, link color,
|
|
background appears on hover for affordance. Scoped to exclude
|
|
user bubbles so they keep their primary-tinted chip styling. */
|
|
.markdown-body:not(.markdown-body-user) a > code,
|
|
.markdown-body:not(.markdown-body-user) a code:not(pre code) {
|
|
background: transparent;
|
|
border: none;
|
|
color: inherit;
|
|
}
|
|
|
|
.markdown-body:not(.markdown-body-user) a:hover > code,
|
|
.markdown-body:not(.markdown-body-user) a:hover code:not(pre code) {
|
|
background: color-mix(in oklch, var(--foreground) 10%, var(--muted));
|
|
}
|
|
|
|
.markdown-body blockquote {
|
|
border-left: 3px solid var(--primary);
|
|
padding-left: 0.75rem;
|
|
margin-left: 0;
|
|
margin-top: 0.5rem;
|
|
margin-bottom: 0.5rem;
|
|
color: var(--muted-foreground);
|
|
font-style: italic;
|
|
}
|
|
|
|
.markdown-body hr {
|
|
border: none;
|
|
border-top: 1px solid var(--border);
|
|
margin: 1.5rem 0;
|
|
}
|
|
|
|
.markdown-body table {
|
|
border-collapse: collapse;
|
|
/* width:100% fills the container and pins the table to it, so it can never
|
|
shrink-to-fit and grow into the surrounding overflow-x-auto scroll
|
|
container (which is what produced a horizontal scrollbar under width:auto).
|
|
Long values wrap instead of overflowing. */
|
|
width: 100%;
|
|
margin: 0.75rem 0;
|
|
table-layout: auto;
|
|
}
|
|
|
|
.markdown-table-scroll {
|
|
position: relative;
|
|
}
|
|
|
|
.markdown-table-resizer {
|
|
position: absolute;
|
|
z-index: 10;
|
|
width: 0.625rem;
|
|
padding: 0;
|
|
transform: translateX(-50%);
|
|
cursor: col-resize;
|
|
touch-action: none;
|
|
border: 0;
|
|
outline: none;
|
|
background: transparent;
|
|
}
|
|
|
|
.markdown-table-resizer::after {
|
|
position: absolute;
|
|
top: 0;
|
|
bottom: 0;
|
|
left: 50%;
|
|
width: 2px;
|
|
content: "";
|
|
transform: translateX(-50%);
|
|
background: transparent;
|
|
transition: background-color 100ms ease;
|
|
}
|
|
|
|
.markdown-table-resizer:hover::after,
|
|
.markdown-table-resizer:focus-visible::after,
|
|
.markdown-table-resizer[data-active="true"]::after {
|
|
background: var(--primary);
|
|
}
|
|
|
|
.markdown-body th,
|
|
.markdown-body td {
|
|
border: 1px solid var(--border);
|
|
padding: 0.25rem 0.5rem;
|
|
font-size: 13px;
|
|
vertical-align: top;
|
|
overflow-wrap: anywhere;
|
|
white-space: normal;
|
|
}
|
|
|
|
/* Keep genuinely wide Markdown tables readable in their local scroll wrapper.
|
|
Ordinary two- and three-column tables use the available width and wrap. */
|
|
.markdown-body table:has(> thead > tr > th:nth-child(4)) :is(th, td) {
|
|
min-width: 8rem;
|
|
}
|
|
|
|
.markdown-body th {
|
|
background: var(--muted);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.markdown-body td:not(:first-child) code {
|
|
white-space: normal;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.markdown-body thead {
|
|
background: color-mix(in oklch, var(--muted) 50%, transparent);
|
|
}
|
|
|
|
.markdown-body tbody tr {
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.markdown-body tbody tr:last-child {
|
|
border-bottom: 0;
|
|
}
|
|
|
|
.markdown-body tbody tr:hover {
|
|
background: color-mix(in oklch, var(--muted) 50%, transparent);
|
|
}
|
|
|
|
.markdown-body strong {
|
|
color: var(--foreground);
|
|
font-weight: 700;
|
|
}
|
|
|
|
/* User message markdown overrides for primary background */
|
|
.markdown-body-user :not(pre) > code,
|
|
.markdown-body-user code:not(pre code) {
|
|
background: color-mix(in oklch, var(--primary) 20%, transparent);
|
|
color: var(--foreground);
|
|
}
|
|
|
|
/* TipTap editor styles */
|
|
.tiptap p.is-editor-empty:first-child::before {
|
|
content: attr(data-placeholder);
|
|
float: left;
|
|
color: var(--muted-foreground);
|
|
pointer-events: none;
|
|
height: 0;
|
|
}
|
|
|
|
.tiptap p {
|
|
margin: 0;
|
|
}
|
|
|
|
/* Inline code */
|
|
.tiptap code {
|
|
background-color: var(--muted);
|
|
border-radius: 0.25rem;
|
|
padding: 0.125rem 0.25rem;
|
|
font-size: 0.75rem;
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
}
|
|
|
|
/* Code blocks */
|
|
.tiptap pre {
|
|
background-color: color-mix(in oklch, var(--card) 92%, var(--foreground) 8%);
|
|
border: 1px solid var(--border);
|
|
border-radius: 0.375rem;
|
|
padding: 0.5rem 0.75rem;
|
|
margin: 0.25rem 0;
|
|
overflow-x: auto;
|
|
position: relative;
|
|
}
|
|
|
|
.tiptap pre code {
|
|
background: none;
|
|
padding: 0;
|
|
border-radius: 0;
|
|
font-size: 0.75rem;
|
|
line-height: 1.4;
|
|
font-family: var(--font-mono, ui-monospace, monospace);
|
|
}
|
|
|
|
/* Language selector on code blocks */
|
|
.tiptap pre .code-block-language {
|
|
position: absolute;
|
|
top: 0.25rem;
|
|
right: 0.25rem;
|
|
font-size: 0.625rem;
|
|
font-family: var(--font-sans, ui-sans-serif, sans-serif);
|
|
color: var(--muted-foreground);
|
|
background: var(--muted);
|
|
border: 1px solid var(--border);
|
|
border-radius: 0.25rem;
|
|
padding: 0.0625rem 0.25rem;
|
|
cursor: pointer;
|
|
outline: none;
|
|
opacity: 0;
|
|
transition: opacity 0.15s;
|
|
}
|
|
|
|
.tiptap pre:hover .code-block-language,
|
|
.tiptap pre:focus-within .code-block-language {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* Lowlight / highlight.js syntax colors */
|
|
.tiptap pre code .hljs-comment,
|
|
.tiptap pre code .hljs-quote {
|
|
color: var(--muted-foreground);
|
|
font-style: italic;
|
|
}
|
|
|
|
.tiptap pre code .hljs-keyword,
|
|
.tiptap pre code .hljs-selector-tag,
|
|
.tiptap pre code .hljs-built_in {
|
|
color: var(--primary);
|
|
}
|
|
|
|
.tiptap pre code .hljs-string,
|
|
.tiptap pre code .hljs-attr,
|
|
.tiptap pre code .hljs-addition {
|
|
color: oklch(0.7 0.15 150);
|
|
}
|
|
|
|
.tiptap pre code .hljs-number,
|
|
.tiptap pre code .hljs-literal {
|
|
color: oklch(0.7 0.15 60);
|
|
}
|
|
|
|
.tiptap pre code .hljs-title,
|
|
.tiptap pre code .hljs-section,
|
|
.tiptap pre code .hljs-type {
|
|
color: oklch(0.62 0.11 198);
|
|
}
|
|
|
|
.tiptap pre code .hljs-name,
|
|
.tiptap pre code .hljs-tag {
|
|
color: var(--destructive);
|
|
}
|
|
|
|
.tiptap pre code .hljs-variable,
|
|
.tiptap pre code .hljs-template-variable {
|
|
color: oklch(0.62 0.12 48);
|
|
}
|
|
|
|
.tiptap pre code .hljs-regexp,
|
|
.tiptap pre code .hljs-link {
|
|
color: oklch(0.7 0.15 30);
|
|
}
|
|
|
|
.tiptap pre code .hljs-symbol,
|
|
.tiptap pre code .hljs-bullet {
|
|
color: oklch(0.65 0.2 330);
|
|
}
|
|
|
|
.tiptap pre code .hljs-meta {
|
|
color: var(--muted-foreground);
|
|
}
|
|
|
|
.tiptap pre code .hljs-deletion {
|
|
color: var(--destructive);
|
|
}
|
|
|
|
.tiptap pre code .hljs-emphasis {
|
|
font-style: italic;
|
|
}
|
|
|
|
.tiptap pre code .hljs-strong {
|
|
font-weight: bold;
|
|
}
|
|
|
|
/* Monaco Editor - Comment decorations */
|
|
.monaco-comment-line {
|
|
background-color: color-mix(in oklab, var(--primary) 12%, transparent) !important;
|
|
}
|
|
|
|
/* Lines-decoration lane for commented lines, clickable bar */
|
|
.monaco-comment-bar {
|
|
cursor: pointer !important;
|
|
background-color: color-mix(in oklab, var(--primary) 12%, transparent) !important;
|
|
border-left: 3px solid color-mix(in oklab, var(--primary) 58%, transparent) !important;
|
|
}
|
|
.monaco-comment-bar:hover {
|
|
background-color: color-mix(in oklab, var(--primary) 20%, transparent) !important;
|
|
}
|
|
|
|
/* Chat bubble icon on the bar (first line of a comment only) */
|
|
.monaco-comment-bar-icon {
|
|
cursor: pointer !important;
|
|
position: relative !important;
|
|
background-color: color-mix(in oklab, var(--primary) 12%, transparent) !important;
|
|
border-left: 3px solid color-mix(in oklab, var(--primary) 58%, transparent) !important;
|
|
}
|
|
.monaco-comment-bar-icon:hover {
|
|
background-color: color-mix(in oklab, var(--primary) 20%, transparent) !important;
|
|
}
|
|
.monaco-comment-bar-icon::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
width: 12px;
|
|
height: 12px;
|
|
background: var(--primary);
|
|
mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z'/></svg>");
|
|
-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z'/></svg>");
|
|
mask-size: contain;
|
|
-webkit-mask-size: contain;
|
|
}
|
|
|
|
/* Line number bg tint for commented lines */
|
|
.monaco-comment-line-number {
|
|
background-color: color-mix(in oklab, var(--primary) 12%, transparent) !important;
|
|
}
|
|
|
|
/* TipTap Plan Editor Styles
|
|
Element styles (headings, lists, code, etc.) come from .markdown-body above.
|
|
Only TipTap-specific layout, container, and editor behavior styles remain here. */
|
|
.tiptap-plan-wrapper {
|
|
height: 100%;
|
|
overflow: auto;
|
|
border-radius: 0;
|
|
}
|
|
|
|
.tiptap-plan-wrapper:not(.dark) {
|
|
background: var(--background);
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tiptap {
|
|
height: 100%;
|
|
padding: 0.75rem;
|
|
outline: none;
|
|
cursor: text;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tiptap:focus {
|
|
outline: none;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tableWrapper {
|
|
position: relative;
|
|
max-width: 100%;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tableWrapper :is(th, td) {
|
|
position: relative;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .column-resize-handle {
|
|
position: absolute;
|
|
z-index: 20;
|
|
top: 0;
|
|
right: -0.3125rem;
|
|
bottom: -1px;
|
|
width: 0.625rem;
|
|
pointer-events: none;
|
|
touch-action: none;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .column-resize-handle::after {
|
|
position: absolute;
|
|
top: 0;
|
|
bottom: 0;
|
|
left: 50%;
|
|
width: 2px;
|
|
content: "";
|
|
transform: translateX(-50%);
|
|
background: var(--primary);
|
|
}
|
|
|
|
.tiptap-plan-wrapper .resize-cursor,
|
|
.tiptap-plan-wrapper .resize-cursor * {
|
|
cursor: col-resize !important;
|
|
}
|
|
|
|
/* Task lists (TipTap-specific data attribute) */
|
|
.tiptap-plan-wrapper .tiptap ul[data-type="taskList"] {
|
|
list-style: none !important;
|
|
padding-left: 0 !important;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tiptap ul[data-type="taskList"] li {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tiptap ul[data-type="taskList"] li label {
|
|
margin-top: 0.125rem;
|
|
}
|
|
|
|
/* Code blocks (TipTap-specific: lowlight/highlight.js syntax highlighting) */
|
|
.tiptap-plan-wrapper .tiptap pre {
|
|
background: var(--background) !important;
|
|
padding: 0.5rem 0.75rem !important;
|
|
border-radius: 0.375rem !important;
|
|
overflow-x: auto !important;
|
|
margin-top: 0.5rem !important;
|
|
margin-bottom: 0.5rem !important;
|
|
}
|
|
|
|
.tiptap-plan-wrapper:not(.dark) .tiptap pre {
|
|
background: var(--muted) !important;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tiptap pre code {
|
|
background: transparent !important;
|
|
color: var(--foreground);
|
|
padding: 0 !important;
|
|
font-size: var(--font-mono-size) !important;
|
|
font-family: var(--font-mono) !important;
|
|
}
|
|
|
|
.tiptap-plan-wrapper:not(.dark) .tiptap pre code {
|
|
color: var(--foreground);
|
|
}
|
|
|
|
/* Highlight marks */
|
|
.tiptap-plan-wrapper mark {
|
|
background-color: color-mix(in oklab, oklch(0.84 0.12 92) 38%, transparent);
|
|
border-radius: 2px;
|
|
padding: 1px 0;
|
|
}
|
|
|
|
/* Comment highlights, inline mark spans like Highlight extension */
|
|
.tiptap-plan-wrapper .comment-highlight,
|
|
.agent-message-comment-body .comment-highlight {
|
|
background-color: color-mix(in oklch, var(--accent) 70%, transparent);
|
|
color: inherit;
|
|
border-radius: 3px;
|
|
border-bottom: 2px solid color-mix(in oklch, var(--accent-foreground) 25%, transparent);
|
|
cursor: pointer;
|
|
transition: background-color 0.15s ease;
|
|
padding: 2px 1px;
|
|
box-decoration-break: clone;
|
|
-webkit-box-decoration-break: clone;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .comment-highlight:hover,
|
|
.agent-message-comment-body .comment-highlight:hover {
|
|
background-color: color-mix(in oklch, var(--accent) 90%, transparent);
|
|
}
|
|
|
|
.agent-message-comment-fallback {
|
|
position: absolute;
|
|
pointer-events: none;
|
|
background-color: color-mix(in oklch, var(--accent) 70%, transparent);
|
|
border-radius: 3px;
|
|
border-bottom: 2px solid color-mix(in oklch, var(--accent-foreground) 25%, transparent);
|
|
}
|
|
|
|
/* Comment badge, single widget decoration at end of mark range */
|
|
.tiptap-plan-wrapper .comment-badge,
|
|
.agent-message-comment-body .comment-badge {
|
|
position: relative;
|
|
display: inline-block;
|
|
width: 0;
|
|
height: 0;
|
|
overflow: visible;
|
|
vertical-align: top;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .comment-badge svg,
|
|
.agent-message-comment-body .comment-badge svg {
|
|
position: absolute;
|
|
top: -6px;
|
|
left: 2px;
|
|
width: 11px;
|
|
height: 11px;
|
|
color: color-mix(in oklab, var(--primary) 80%, var(--foreground));
|
|
cursor: pointer;
|
|
transition: color 0.15s ease;
|
|
pointer-events: auto;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .comment-badge:hover svg,
|
|
.agent-message-comment-body .comment-badge:hover svg,
|
|
.agent-message-comment-body .comment-badge:focus-visible svg {
|
|
color: var(--primary);
|
|
}
|
|
|
|
.agent-message-comment-body .comment-badge:focus-visible svg {
|
|
outline: 2px solid var(--ring);
|
|
outline-offset: 2px;
|
|
border-radius: 2px;
|
|
}
|
|
|
|
.markdown-preview-source-block {
|
|
position: relative;
|
|
}
|
|
|
|
.markdown-preview-commented-range {
|
|
background-color: color-mix(in oklch, var(--accent) 46%, transparent);
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
box-decoration-break: clone;
|
|
-webkit-box-decoration-break: clone;
|
|
}
|
|
|
|
.markdown-preview-commented-range:hover {
|
|
background-color: color-mix(in oklch, var(--accent) 62%, transparent);
|
|
}
|
|
|
|
.markdown-preview-comment-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 18px;
|
|
height: 18px;
|
|
margin-left: 6px;
|
|
color: var(--primary);
|
|
vertical-align: middle;
|
|
border: 1px solid color-mix(in oklch, var(--primary) 35%, transparent);
|
|
border-radius: 4px;
|
|
background-color: color-mix(in oklch, var(--background) 88%, transparent);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.markdown-preview-comment-badge:hover {
|
|
color: var(--primary-foreground);
|
|
background-color: var(--primary);
|
|
}
|
|
|
|
.markdown-preview-pre-comment-wrapper {
|
|
position: relative;
|
|
}
|
|
|
|
.markdown-preview-pre-comment-wrapper .markdown-preview-comment-badge {
|
|
position: absolute;
|
|
top: 6px;
|
|
right: 6px;
|
|
margin-left: 0;
|
|
}
|
|
|
|
/* Drag handle */
|
|
.plan-drag-handle {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 20px;
|
|
height: 20px;
|
|
margin-left: 4px;
|
|
border-radius: 4px;
|
|
color: var(--muted-foreground);
|
|
opacity: 0;
|
|
cursor: grab;
|
|
transition:
|
|
opacity 0.15s,
|
|
background-color 0.15s;
|
|
}
|
|
|
|
.plan-drag-handle:hover {
|
|
background-color: var(--muted);
|
|
opacity: 1 !important;
|
|
}
|
|
|
|
.tiptap-plan-wrapper:hover .plan-drag-handle {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.plan-drag-handle:active {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
/* Mermaid diagram styles */
|
|
.tiptap-plan-wrapper .mermaid-container {
|
|
position: relative;
|
|
width: fit-content;
|
|
max-width: 100%;
|
|
margin: 0.75rem auto !important;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .mermaid-container svg {
|
|
max-width: 100% !important;
|
|
height: auto !important;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .mermaid-error {
|
|
color: var(--destructive) !important;
|
|
font-size: 0.75rem !important;
|
|
padding: 0.5rem !important;
|
|
white-space: pre-wrap !important;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tiptap pre.mermaid-code-view {
|
|
margin: 0 !important;
|
|
padding: 0.75rem !important;
|
|
font-size: 0.75rem !important;
|
|
line-height: 1.6 !important;
|
|
white-space: pre-wrap !important;
|
|
background: transparent !important;
|
|
border: none !important;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tiptap pre.mermaid-code-view code {
|
|
color: var(--foreground) !important;
|
|
font-family: var(--font-mono) !important;
|
|
font-size: 0.75rem !important;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tiptap pre.mermaid-code-view .mm-keyword {
|
|
color: var(--primary);
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tiptap pre.mermaid-code-view .mm-arrow {
|
|
color: oklch(0.7 0.15 60);
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tiptap pre.mermaid-code-view .mm-label {
|
|
color: oklch(0.7 0.15 150);
|
|
}
|
|
|
|
.tiptap-plan-wrapper .tiptap pre.mermaid-code-view .mm-text {
|
|
color: var(--muted-foreground);
|
|
}
|
|
|
|
.tiptap-plan-wrapper:not(.dark) .tiptap pre.mermaid-code-view .mm-keyword {
|
|
color: var(--primary);
|
|
}
|
|
|
|
.tiptap-plan-wrapper:not(.dark) .tiptap pre.mermaid-code-view .mm-arrow {
|
|
color: oklch(0.5 0.15 40);
|
|
}
|
|
|
|
.tiptap-plan-wrapper:not(.dark) .tiptap pre.mermaid-code-view .mm-label {
|
|
color: oklch(0.4 0.15 150);
|
|
}
|
|
|
|
.tiptap-plan-wrapper .mermaid-toolbar {
|
|
position: absolute;
|
|
top: 0.375rem;
|
|
right: 0.375rem;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
padding: 0.125rem 0.375rem;
|
|
border-radius: 0.375rem;
|
|
border: 1px solid oklch(from var(--border) l c h / 0.5);
|
|
background: var(--popover);
|
|
opacity: 0;
|
|
transition: opacity 0.15s;
|
|
z-index: 10;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .mermaid-container:hover .mermaid-toolbar {
|
|
opacity: 1;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .mermaid-zoom-btn {
|
|
padding: 0.125rem 0.25rem;
|
|
font-size: 0.75rem;
|
|
color: var(--muted-foreground);
|
|
cursor: pointer;
|
|
line-height: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .mermaid-zoom-btn:hover {
|
|
color: var(--foreground);
|
|
}
|
|
|
|
.tiptap-plan-wrapper .mermaid-zoom-label {
|
|
font-size: 10px;
|
|
color: var(--muted-foreground);
|
|
cursor: pointer;
|
|
font-variant-numeric: tabular-nums;
|
|
min-width: 3ch;
|
|
text-align: center;
|
|
}
|
|
|
|
.tiptap-plan-wrapper .mermaid-zoom-label:hover {
|
|
color: var(--foreground);
|
|
}
|
|
|
|
.tiptap-plan-wrapper .mermaid-toolbar-sep {
|
|
width: 1px;
|
|
height: 0.875rem;
|
|
background: oklch(from var(--border) l c h / 0.5);
|
|
margin: 0 0.125rem;
|
|
}
|
|
|
|
/* Mermaid diagram in markdown renderer (chat messages, PR comments) */
|
|
.mermaid-block svg {
|
|
max-width: 100%;
|
|
height: auto;
|
|
}
|
|
|
|
/* Placeholder for empty plan editor */
|
|
.tiptap-plan-wrapper .tiptap p.is-editor-empty:first-child::before {
|
|
content: attr(data-placeholder);
|
|
float: left;
|
|
color: var(--muted-foreground);
|
|
opacity: 0.5;
|
|
pointer-events: none;
|
|
height: 0;
|
|
font-size: 13px;
|
|
}
|
|
|
|
/* Monaco Editor - Diff gutter indicators (colors from --git-addition / --git-deletion CSS vars) */
|
|
.monaco-diff-added-gutter {
|
|
width: 3px !important;
|
|
margin-left: 3px;
|
|
background-color: rgb(var(--git-addition)) !important;
|
|
}
|
|
.monaco-diff-modified-gutter {
|
|
width: 3px !important;
|
|
margin-left: 3px;
|
|
background-color: rgb(var(--git-addition)) !important;
|
|
}
|
|
.monaco-diff-deleted-gutter {
|
|
width: 0 !important;
|
|
margin-left: 2px;
|
|
border-left: 4px solid rgb(var(--git-deletion)) !important;
|
|
}
|
|
|
|
/* Monaco Editor - Gutter comment hint ("+" hover on decoration lane) */
|
|
.monaco-gutter-comment-hint {
|
|
cursor: pointer !important;
|
|
position: relative !important;
|
|
}
|
|
.monaco-gutter-comment-hint::after {
|
|
content: "+";
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 14px;
|
|
height: 14px;
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
line-height: 1;
|
|
color: var(--primary-foreground);
|
|
border-radius: 3px;
|
|
background-color: var(--primary);
|
|
}
|
|
|
|
/* Monaco Editor - Gutter line selection highlight */
|
|
.monaco-gutter-selected-line {
|
|
background-color: color-mix(in oklab, var(--primary) 15%, transparent) !important;
|
|
}
|
|
.monaco-gutter-selected-deco {
|
|
background-color: color-mix(in oklab, var(--primary) 15%, transparent) !important;
|
|
}
|
|
|
|
/* Monaco Editor - Walkthrough active range */
|
|
.monaco-walkthrough-line {
|
|
background-color: color-mix(in oklab, var(--primary) 11%, transparent) !important;
|
|
}
|
|
.monaco-walkthrough-line-number {
|
|
background-color: color-mix(in oklab, var(--primary) 15%, transparent) !important;
|
|
color: var(--foreground) !important;
|
|
}
|
|
.monaco-walkthrough-range,
|
|
.monaco-walkthrough-range-start {
|
|
background-color: color-mix(in oklab, var(--primary) 10%, transparent) !important;
|
|
}
|
|
.monaco-walkthrough-range-start {
|
|
border-left: 3px solid color-mix(in oklab, var(--primary) 72%, transparent) !important;
|
|
}
|
|
|
|
/* Monaco Editor - Peek view / references widget overrides */
|
|
.settings-prompt-editor .monaco-editor .suggest-widget {
|
|
/* Keep completion rows above the mobile settings save bar. */
|
|
z-index: 50;
|
|
}
|
|
|
|
.monaco-editor .peekview-widget .head {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.monaco-editor .peekview-widget .head .peekview-title .filename {
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.monaco-editor .peekview-widget .head .peekview-title .dirname {
|
|
font-size: 11px;
|
|
}
|
|
|
|
/* Match references list font size to editor font size */
|
|
.monaco-editor .reference-zone-widget .ref-tree .monaco-list-row {
|
|
font-size: var(--font-mono-size) !important;
|
|
height: 20px !important;
|
|
line-height: 20px !important;
|
|
}
|
|
|
|
.monaco-editor .reference-zone-widget .ref-tree .reference-file {
|
|
font-size: var(--font-mono-size) !important;
|
|
height: 22px !important;
|
|
line-height: 22px !important;
|
|
}
|
|
|
|
.monaco-editor .reference-zone-widget .ref-tree .monaco-tl-contents {
|
|
padding-left: 4px;
|
|
}
|
|
|
|
.monaco-editor .reference-zone-widget .ref-tree .reference-file .count {
|
|
font-size: 10px;
|
|
line-height: 14px;
|
|
padding: 0 5px;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
/* Pipeline node glow for running tasks — static ring on the element, the pulse
|
|
* is opacity-only on a pseudo-element so it composites on the GPU rather than
|
|
* repainting the box-shadow every frame. */
|
|
@keyframes node-border-glow {
|
|
0%,
|
|
100% {
|
|
opacity: 0.5;
|
|
}
|
|
50% {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.node-border-running {
|
|
position: relative;
|
|
box-shadow: 0 0 0 1px color-mix(in oklab, var(--primary) 42%, var(--border));
|
|
}
|
|
|
|
.node-border-running::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
border-radius: inherit;
|
|
pointer-events: none;
|
|
box-shadow:
|
|
0 0 0 1px color-mix(in oklab, var(--primary) 68%, var(--border)),
|
|
0 0 0 3px color-mix(in oklab, var(--primary) 12%, transparent);
|
|
animation: node-border-glow 2.8s ease-in-out infinite;
|
|
}
|
|
|
|
.chat-message-list {
|
|
font-size: 13px;
|
|
font-family:
|
|
-apple-system, "system-ui", "Segoe UI", "Noto Sans", Helvetica, Arial, "NerdFontLocalGlyphs",
|
|
"NerdFontBundledGlyphs", sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
|
}
|
|
|
|
/* Shiki code block styling */
|
|
.shiki-code-block pre.shiki {
|
|
margin: 0;
|
|
padding: 8px 12px;
|
|
white-space: pre-wrap;
|
|
overflow-wrap: anywhere;
|
|
font-size: var(--font-mono-size);
|
|
line-height: 1.5;
|
|
background-color: var(--background) !important;
|
|
}
|
|
|
|
.shiki-code-block pre.shiki code {
|
|
font-family: var(--font-geist-mono, ui-monospace, monospace);
|
|
}
|
|
|
|
.debug {
|
|
border: 1px solid var(--destructive) !important;
|
|
}
|
|
|
|
/* Panel search highlights */
|
|
.search-highlight {
|
|
background: color-mix(in oklab, oklch(0.86 0.13 92) 42%, transparent);
|
|
border-radius: 2px;
|
|
}
|
|
.search-highlight-current {
|
|
background: color-mix(in oklab, var(--warning) 56%, transparent);
|
|
outline: 1px solid color-mix(in oklab, var(--warning) 78%, var(--border));
|
|
border-radius: 2px;
|
|
}
|
|
.search-flash {
|
|
animation: search-flash 1.2s ease-out;
|
|
}
|
|
@keyframes search-flash {
|
|
0% {
|
|
background-color: color-mix(in oklab, var(--warning) 48%, transparent);
|
|
}
|
|
100% {
|
|
background-color: transparent;
|
|
}
|
|
}
|
|
|
|
/* One-shot destination cue for workspace content-search editor reveals. */
|
|
.editor-content-search-flash {
|
|
background-color: color-mix(in oklab, var(--warning) 34%, transparent);
|
|
/* Keep duration in sync with EDITOR_CONTENT_SEARCH_FLASH_DURATION_MS. */
|
|
animation: editor-content-search-flash 1.2s ease-out forwards;
|
|
}
|
|
@keyframes editor-content-search-flash {
|
|
from {
|
|
background-color: color-mix(in oklab, var(--warning) 34%, transparent);
|
|
}
|
|
to {
|
|
background-color: transparent;
|
|
}
|
|
}
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.editor-content-search-flash {
|
|
animation: none;
|
|
}
|
|
}
|
|
|
|
/* Highlights a review finding card after "go to finding" scrolls it into view,
|
|
* so the eye lands on the right card among several inline in the diff. */
|
|
.review-finding-flash {
|
|
animation: review-finding-flash 1.4s ease-out;
|
|
}
|
|
@keyframes review-finding-flash {
|
|
0% {
|
|
box-shadow: 0 0 0 2px color-mix(in oklab, var(--primary) 70%, transparent);
|
|
background-color: color-mix(in oklab, var(--primary) 16%, transparent);
|
|
}
|
|
100% {
|
|
box-shadow: 0 0 0 2px transparent;
|
|
background-color: transparent;
|
|
}
|
|
}
|
|
|
|
/* Queue panel collapsible — animate height + opacity using the Radix
|
|
* Collapsible CSS variable. Used by QueueAffordance so opening/closing the
|
|
* queued-messages panel feels intentional rather than popping. */
|
|
@keyframes queue-panel-open {
|
|
from {
|
|
height: 0;
|
|
opacity: 0;
|
|
}
|
|
to {
|
|
height: var(--radix-collapsible-content-height);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
@keyframes queue-panel-close {
|
|
from {
|
|
height: var(--radix-collapsible-content-height);
|
|
opacity: 1;
|
|
}
|
|
to {
|
|
height: 0;
|
|
opacity: 0;
|
|
}
|
|
}
|
|
.animate-queue-open {
|
|
animation: queue-panel-open 220ms cubic-bezier(0.32, 0.72, 0, 1);
|
|
}
|
|
.animate-queue-close {
|
|
animation: queue-panel-close 180ms cubic-bezier(0.32, 0.72, 0, 1);
|
|
}
|
|
|
|
/* Unified AppSidebar — header/text content fades in when the rail expands
|
|
* from its collapsed (icon-only) state. */
|
|
@keyframes app-sidebar-fade-in {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateX(-4px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
}
|
|
.sidebar-fade-in {
|
|
animation: app-sidebar-fade-in 200ms ease-out;
|
|
}
|
|
|
|
/* AppSidebar section expand/collapse — a quick height animation that pushes
|
|
* sibling sections, replacing the old opacity fade. Driven by the Radix
|
|
* Collapsible `data-state` + content-height CSS var. */
|
|
@keyframes sidebar-section-expand {
|
|
from {
|
|
height: 0;
|
|
}
|
|
to {
|
|
height: var(--radix-collapsible-content-height);
|
|
}
|
|
}
|
|
@keyframes sidebar-section-collapse {
|
|
from {
|
|
height: var(--radix-collapsible-content-height);
|
|
}
|
|
to {
|
|
height: 0;
|
|
}
|
|
}
|
|
.sidebar-section-content {
|
|
overflow: hidden;
|
|
}
|
|
.sidebar-section-content[data-state="open"] {
|
|
animation: sidebar-section-expand 180ms cubic-bezier(0.32, 0.72, 0, 1);
|
|
}
|
|
.sidebar-section-content[data-state="closed"] {
|
|
animation: sidebar-section-collapse 160ms cubic-bezier(0.32, 0.72, 0, 1);
|
|
}
|
|
|
|
/* Installed desktop PWAs can place app chrome inside the native title bar.
|
|
* The live geometry variables come from navigator.windowControlsOverlay, so
|
|
* controls remain clear of either platform's left- or right-side buttons. */
|
|
[data-window-controls-overlay="visible"] [data-window-controls-overlay-region] {
|
|
-webkit-app-region: drag;
|
|
height: max(2.5rem, var(--titlebar-area-height));
|
|
min-height: max(2.5rem, var(--titlebar-area-height));
|
|
}
|
|
|
|
[data-window-controls-overlay="visible"]
|
|
[data-window-controls-overlay-region]
|
|
:is(a, button, input, select, textarea, [role="button"], [tabindex]) {
|
|
-webkit-app-region: no-drag;
|
|
}
|
|
|
|
[data-window-controls-overlay="visible"] [data-window-controls-overlay-region="sidebar"] {
|
|
padding-left: calc(var(--titlebar-area-x) + 0.75rem);
|
|
}
|
|
|
|
[data-window-controls-overlay="visible"]
|
|
[data-testid="app-sidebar"][data-collapsed="true"]
|
|
[data-window-controls-overlay-region="sidebar"] {
|
|
width: calc(var(--titlebar-area-x) + 4rem);
|
|
flex-direction: row;
|
|
gap: 0.25rem;
|
|
padding-top: 0;
|
|
padding-right: 0;
|
|
padding-bottom: 0;
|
|
}
|
|
|
|
[data-window-controls-overlay="visible"]:has([data-testid="app-sidebar"][data-collapsed="true"])
|
|
[data-window-controls-overlay-region="content"] {
|
|
padding-left: calc(var(--titlebar-area-x) + 0.5rem);
|
|
}
|
|
|
|
[data-window-controls-overlay="visible"] [data-window-controls-overlay-region="content"] {
|
|
padding-right: max(
|
|
0.75rem,
|
|
calc(100vw - var(--titlebar-area-x) - var(--titlebar-area-width) + 0.75rem)
|
|
);
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.sidebar-fade-in,
|
|
.sidebar-section-content[data-state="open"],
|
|
.sidebar-section-content[data-state="closed"] {
|
|
animation: none;
|
|
}
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
[data-chat-text-motion],
|
|
[data-chat-motion-item] {
|
|
opacity: 1 !important;
|
|
transform: none !important;
|
|
}
|
|
}
|