Files
openchamber/packages/ui/src/styles/design-system.css
T
Bohdan Triapitsyn 1291cde5c2 feat(ui): sidebar redesign — project zones, grouping modes, full-page surfaces (#2480)
* checkpoint: flatten sidebar core (flat sessions, zones, single mode, folders flat)

* checkpoint: sidebar nav + scheduled/archive full-page surfaces, recent zone header

* checkpoint: worktrees management surface via project menu

* checkpoint: docs, i18n, validation for sidebar redesign

* checkpoint: unified row/zone geometry, recent backfill, tooltips everywhere, primary spinner

* checkpoint: branch icon marker, date moved to rich tooltip, recent back to pure time window

* checkpoint: PR state on branch markers + tooltip, no reserved right space, aligned show-more, instant tooltips

* checkpoint: reserve hover-action space so title text is not overlapped

* checkpoint: tighten hover-action reserve

* checkpoint: color-only unread emphasis to avoid title reflow

* checkpoint: drop new-subfolder action, folder actions overlay on hover

* checkpoint: fix sticky project headers (sticky on trigger div), stuck elevation

* checkpoint: full-bleed semibold zone headers, no top scroll fade

* checkpoint: headers without background tint (typography-only emphasis)

* checkpoint: recent header flush with scroll top (no pre-stick bump)

* checkpoint: shared tooltip provider with grouping (instant handoff between rows)

* checkpoint: blur pointer-click focus so hover chrome hides on mouse-leave

* checkpoint: tooltip closeDelay bridges inter-row gap

* checkpoint: nav above controls, merged view dropdown, project-scoped bulk selection, cross-worktree folders

* checkpoint: folder header tooltip with full path name

* checkpoint: true page surfaces (hidden chat, header title, close-on-select), multirun page, run-now jump, folders on top, controls row polish

* checkpoint: rename mode — dual-instance outside-click fix, no vertical shift

* checkpoint: session grouping mode toggle (by-worktree default, flat option)

* checkpoint: worktree header — hover padding reserve + delete worktree action

* checkpoint: frosted sticky header backing under desktop vibrancy

* checkpoint: align worktree sub-header with project header icon column

* checkpoint: restore worktree group DnD reorder; dense vibrancy header tint (Chromium mask+backdrop-filter)

* checkpoint: vibrancy — drop scroller mask so backdrop-filter samples rows (Chromium backdrop-root limitation)

* checkpoint: vibrancy headers use opaque sidebar tone (Electron transparent-window backdrop-filter bug)

* checkpoint: nav collapsed to one row (New session + surface icons), mirrors Add project row

* checkpoint: raise sticky zone headers above row action layers (z-20)

* checkpoint: New session as full-width CTA + single quiet toolbar row

* checkpoint: New session row back to quiet text form above the toolbar

* checkpoint: align toolbar left icon with New session icon column

* checkpoint: hoverless flat header controls (color-only hover states)

* checkpoint: sticky project headers toggle in view dropdown (default on)

* checkpoint: full-page surfaces adapted — archive directory filter panel, scheduled master-detail, multirun without duplicate title bar

* checkpoint: multirun joins mutually exclusive surface set

* checkpoint: surfaces leave via navigation only (no close/cancel buttons), robust close-on-new-session, drop dead MultiRunWindow

* checkpoint: no scheduled header description, aligned empty-worktree note, collapse/expand covers worktree groups

* checkpoint: overlay scrollbar above sticky zone headers

* checkpoint: archive delete icons reveal on hover with padding shift

* checkpoint: new worktrees surface at top of the worktree list

* checkpoint: no grab cursor on worktree headers

* checkpoint: worktrees page list-only with inline action, no worktrees in edit dialog, drop menu ellipsis

* checkpoint: worktrees page uses full content width

* checkpoint: worktrees header — 'in' instead of em dash, no description

* checkpoint: drop legacy OpenCode badge from worktree list, tooltip without OpenCode mention

* review: bound pr summary cache
2026-07-28 12:04:39 +03:00

465 lines
18 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@layer base {
:root {
color-scheme: light;
--oc-safe-area-top: 0px;
--oc-safe-area-right: 0px;
--oc-safe-area-bottom: 0px;
--oc-safe-area-bottom-visual: 0px;
--oc-safe-area-left: 0px;
--oc-header-height: 56px;
--oc-visual-viewport-offset-top: 0px;
--oc-visual-viewport-height: 100dvh;
--oc-wco-left-inset: 0px;
--oc-wco-right-inset: 0px;
--oc-wco-titlebar-height: 0px;
--ui-regular-font-weight: 400;
--oc-scrollbar-thumb: oklch(0.32 0.03 50 / 0.4);
--oc-scrollbar-thumb-hover: oklch(0.32 0.03 50 / 0.6);
--padding-scale: 1;
/* Semantic typography defaults (must match SEMANTIC_TYPOGRAPHY) */
--text-markdown: 0.9375rem;
--text-code: 0.8125rem;
--text-ui-header: 0.9375rem;
--text-ui-label: 0.8750rem;
--text-meta: 0.875rem;
--text-micro: 0.875rem;
--text-settings-page-title: 1.125rem;
/* Default Light Theme */
--background: oklch(0.97 0.02 85); /* Warm sand background */
--foreground: oklch(0.25 0.02 40); /* Dark warm text */
--card: oklch(0.99 0.01 90); /* Bright sand card */
--card-foreground: oklch(0.25 0.02 40); /* Dark warm text */
--popover: oklch(0.99 0.01 90); /* Bright sand popover */
--popover-foreground: oklch(0.25 0.02 40); /* Dark warm text */
--primary: oklch(0.65 0.2 55); /* Primary accent - orange */
--primary-foreground: oklch(0.99 0.01 90); /* Light text on primary */
--secondary: oklch(0.92 0.02 80); /* Light sand */
--secondary-foreground: oklch(0.25 0.02 40); /* Dark warm text */
--muted: oklch(0.9 0.015 75); /* Muted sand */
--muted-foreground: oklch(0.45 0.02 50); /* Medium warm text */
--accent: oklch(0.92 0.02 80); /* Light sand accent */
--accent-foreground: oklch(0.25 0.02 40); /* Dark warm text */
--destructive: oklch(0.55 0.25 25); /* Warm red */
--destructive-foreground: oklch(0.99 0.01 90); /* Light text */
--border: oklch(0.85 0.02 70); /* Warm border */
--input: oklch(0.88 0.02 75); /* Input background */
--ring: oklch(0.65 0.2 55); /* Focus ring color */
--radius: 0.5625rem;
--chart-1: oklch(0.58 0.15 230); /* Blue */
--chart-2: oklch(0.58 0.15 145); /* Oasis green */
--chart-3: oklch(0.65 0.2 55); /* Orange */
--chart-4: oklch(0.55 0.18 30); /* Rose */
--chart-5: oklch(0.6 0.16 85); /* Golden sand */
--sidebar: oklch(0.95 0.02 80); /* Slightly darker sand */
--sidebar-foreground: oklch(0.25 0.02 40); /* Dark warm text */
--sidebar-primary: oklch(0.65 0.2 55); /* Primary accent */
--sidebar-primary-foreground: oklch(0.99 0.01 90); /* Light text */
--sidebar-accent: oklch(0.9 0.02 75); /* Light sand accent */
--sidebar-accent-foreground: oklch(0.25 0.02 40); /* Dark warm text */
--sidebar-border: oklch(0.85 0.02 70); /* Warm border */
--sidebar-ring: oklch(0.65 0.2 55); /* Focus ring */
--sidebar-stuck-bg: var(--sidebar); /* Desktop sidebar sticky header background (match sidebar) */
}
.dark {
/* Default Dark Theme - using OKLCH color space */
--background: oklch(0.16 0.01 30); /* #151313 */
--foreground: oklch(0.85 0.02 90); /* #cdccc3 */
--card: oklch(0.19 0.01 40); /* #1C1B1A */
--card-foreground: oklch(0.85 0.02 90); /* #cdccc3 */
--popover: oklch(0.24 0.01 40); /* #282726 */
--popover-foreground: oklch(0.85 0.02 90); /* #cdccc3 */
--primary: oklch(0.77 0.17 85); /* #edb449 - golden sand */
--primary-foreground: oklch(0.16 0.01 30); /* #151313 */
--secondary: oklch(0.29 0.01 40); /* #343331 */
--secondary-foreground: oklch(0.85 0.02 90); /* #cdccc3 */
--muted: oklch(0.33 0.01 40); /* #403E3C */
--muted-foreground: oklch(0.75 0.02 80); /* #b6b4ab */
--accent: oklch(0.29 0.01 40); /* #343331 */
--accent-foreground: oklch(0.85 0.02 90); /* #cdccc3 */
--destructive: oklch(0.65 0.15 30); /* #d98678 */
--destructive-foreground: oklch(0.9 0.02 80); /* #e1dcd0 */
--border: oklch(0.31 0.01 35); /* #393836 */
--input: oklch(0.33 0.01 40); /* #403E3C */
--ring: oklch(0.77 0.17 85); /* #edb449 */
--chart-1: oklch(0.68 0.12 230); /* #5aa9d9 - blue */
--chart-2: oklch(0.68 0.12 145); /* #81af6c - green */
--chart-3: oklch(0.7 0.13 95); /* #c2974d - yellow */
--chart-4: oklch(0.65 0.14 45); /* #d8886d - coral */
--chart-5: oklch(0.68 0.12 55); /* #d29470 - orange */
--sidebar: oklch(0.16 0.01 30); /* #151313 */
--sidebar-foreground: oklch(0.85 0.02 90); /* #cdccc3 */
--sidebar-primary: oklch(0.77 0.17 85); /* #edb449 */
--sidebar-primary-foreground: oklch(0.16 0.01 30); /* #151313 */
--sidebar-accent: oklch(0.24 0.01 40); /* #282726 */
--sidebar-accent-foreground: oklch(0.85 0.02 90); /* #cdccc3 */
--sidebar-border: oklch(0.31 0.01 35); /* #393836 */
--sidebar-ring: oklch(0.77 0.17 85); /* #edb449 */
--sidebar-stuck-bg: var(--sidebar); /* Desktop sidebar sticky header background (match sidebar) */
}
* {
border-color: hsl(var(--border));
}
:root * {
border-color: rgba(194, 151, 77, 0.2); /* Warm golden sand borders for light mode */
}
.dark * {
border-color: rgba(57, 56, 54, 0.5); /* #393836 at 50% opacity */
}
body {
background-color: hsl(var(--background));
color: hsl(var(--foreground));
}
* {
@apply border-border outline-none;
}
body {
@apply bg-background text-foreground;
font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif);
font-weight: var(--ui-regular-font-weight, 400);
}
/* Prevent rubber-band scrolling of the page itself.
App scroll should live inside dedicated scroll containers. */
:root,
:root body,
:root #root {
height: 100%;
overflow: hidden;
overscroll-behavior: none;
overscroll-behavior-y: none;
}
:root.desktop-runtime body,
:root.desktop-runtime #root {
background: var(--background) !important;
background-color: var(--background) !important;
}
:root.desktop-runtime[data-oc-vibrancy],
:root.desktop-runtime[data-oc-vibrancy] body,
:root.desktop-runtime[data-oc-vibrancy] #root {
background: transparent !important;
background-color: transparent !important;
}
/* Sticky sidebar zone headers must fully mask the rows scrolling under
them. A frosted (translucent + backdrop-blur) backing is NOT possible
here: Electron's transparent/vibrancy windows break backdrop-filter
entirely (electron#20357 — the backdrop snapshot fails against a
transparent root), so any translucency lets row text bleed through
un-blurred. Use the opaque sidebar tone instead; the blur declaration
stays only as a progressive enhancement if Electron ever fixes it. */
:root.desktop-runtime[data-oc-vibrancy] .oc-zone-header-backing {
background: var(--sidebar-stuck-bg) !important;
background-color: var(--sidebar-stuck-bg) !important;
-webkit-backdrop-filter: blur(16px) saturate(1.2);
backdrop-filter: blur(16px) saturate(1.2);
}
.font-sans {
font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif) !important;
}
.font-mono,
code,
pre {
font-family: var(--font-mono, ui-monospace, SFMono-Regular, 'Liberation Mono', Menlo, monospace) !important;
}
/* Restore default list styling inside markdown content - override Tailwind preflight */
.markdown-content ul,
.markdown-content ol {
padding-left: 2em !important;
}
.markdown-content ul {
list-style-type: none !important;
}
.markdown-content ul > li {
position: relative;
}
.markdown-content ul > li::before {
content: "";
position: absolute;
left: -1.25em;
color: inherit;
}
.markdown-content ol {
list-style-type: decimal !important;
list-style-position: outside !important;
}
.markdown-content li {
display: list-item !important;
}
/* Remove focus rings globally (except inputs/textareas/dropdowns/selects/explicit accent rings) */
*:focus:not(input):not(textarea):not([data-slot="dropdown-menu-content"]):not([data-slot="dropdown-menu-sub-content"]):not([data-slot="select-content"]):not(.focus-ring-accent):not([data-focus-ring="accent"]) {
outline: none !important;
box-shadow: none !important;
}
*:focus-visible:not(input):not(textarea):not([data-slot="dropdown-menu-content"]):not([data-slot="dropdown-menu-sub-content"]):not([data-slot="select-content"]):not(.focus-ring-accent):not([data-focus-ring="accent"]) {
outline: none !important;
box-shadow: none !important;
}
.focus-ring-accent:focus-visible,
[data-focus-ring="accent"]:focus-visible {
outline: 2px solid var(--primary-base) !important;
outline-offset: 2px !important;
box-shadow: none !important;
}
}
@theme inline {
--radius-none: 0;
--radius-sm: 0.25rem; /* 4px */
--radius-md: 0.4375rem; /* 7px */
--radius-lg: 0.5625rem; /* 9px */
--radius-xl: 0.75rem; /* 12px */
--radius-full: 9999px;
/* Semantic spacing aliases (4/8px grid) */
--space-1: var(--spacing-1); /* 4px */
--space-2: var(--spacing-2); /* 8px */
--space-3: var(--spacing-3); /* 12px */
--space-4: var(--spacing-4); /* 16px */
--space-6: var(--spacing-6); /* 24px */
--space-8: var(--spacing-8); /* 32px */
/* Elevation / stacking */
--z-base: 0;
--z-raised: 10;
--z-overlay: 40;
--z-modal: 50;
--transition-fast: 150ms ease-in-out;
/* Override Tailwind spacing scale with custom properties that respect --padding-scale */
--spacing-0: 0;
--spacing-0\.5: calc(0.125rem * var(--padding-scale, 1));
--spacing-1: calc(0.25rem * var(--padding-scale, 1));
--spacing-1\.5: calc(0.375rem * var(--padding-scale, 1));
--spacing-2: calc(0.5rem * var(--padding-scale, 1));
--spacing-2\.5: calc(0.625rem * var(--padding-scale, 1));
--spacing-3: calc(0.75rem * var(--padding-scale, 1));
--spacing-3\.5: calc(0.875rem * var(--padding-scale, 1));
--spacing-4: calc(1rem * var(--padding-scale, 1));
--spacing-5: calc(1.25rem * var(--padding-scale, 1));
--spacing-6: calc(1.5rem * var(--padding-scale, 1));
--spacing-7: calc(1.75rem * var(--padding-scale, 1));
--spacing-8: calc(2rem * var(--padding-scale, 1));
--spacing-9: calc(2.25rem * var(--padding-scale, 1));
--spacing-10: calc(2.5rem * var(--padding-scale, 1));
--spacing-11: calc(2.75rem * var(--padding-scale, 1));
--spacing-12: calc(3rem * var(--padding-scale, 1));
--spacing-14: calc(3.5rem * var(--padding-scale, 1));
--spacing-16: calc(4rem * var(--padding-scale, 1));
--spacing-20: calc(5rem * var(--padding-scale, 1));
--spacing-24: calc(6rem * var(--padding-scale, 1));
--spacing-28: calc(7rem * var(--padding-scale, 1));
--spacing-32: calc(8rem * var(--padding-scale, 1));
--spacing-36: calc(9rem * var(--padding-scale, 1));
--spacing-40: calc(10rem * var(--padding-scale, 1));
--spacing-44: calc(11rem * var(--padding-scale, 1));
--spacing-48: calc(12rem * var(--padding-scale, 1));
--spacing-52: calc(13rem * var(--padding-scale, 1));
--spacing-56: calc(14rem * var(--padding-scale, 1));
--spacing-60: calc(15rem * var(--padding-scale, 1));
--spacing-64: calc(16rem * var(--padding-scale, 1));
--spacing-72: calc(18rem * var(--padding-scale, 1));
--spacing-80: calc(20rem * var(--padding-scale, 1));
--spacing-96: calc(24rem * var(--padding-scale, 1));
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-status-success: var(--status-success);
--color-status-warning: var(--status-warning);
--color-status-error: var(--status-error);
--color-status-info: var(--status-info);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
/* Interactive state tokens (Theme.colors.interactive.*) */
--color-interactive-hover: var(--interactive-hover);
--color-interactive-active: var(--interactive-active);
--color-interactive-selection: var(--interactive-selection);
--color-interactive-selection-foreground: var(--interactive-selection-foreground);
--color-interactive-border-hover: var(--interactive-border-hover);
--color-interactive-border-focus: var(--interactive-border-focus);
--color-interactive-focus-ring: var(--interactive-focus-ring);
/* Short aliases (optional) */
--color-border-hover: var(--interactive-border-hover);
--color-border-focus: var(--interactive-border-focus);
/* Markdown typography variables */
--markdown-body-font-size: var(--text-markdown);
--markdown-body-line-height: var(--markdown-body-line-height);
--markdown-h1-font-size: var(--text-markdown);
--markdown-h1-line-height: var(--markdown-h1-line-height);
--markdown-h2-font-size: var(--text-markdown);
--markdown-h2-line-height: var(--markdown-h2-line-height);
--markdown-h3-font-size: var(--text-markdown);
--markdown-h3-line-height: var(--markdown-h3-line-height);
--markdown-h4-font-size: var(--text-markdown);
--markdown-h4-line-height: var(--markdown-h4-line-height);
--markdown-h5-font-size: var(--text-markdown);
--markdown-h5-line-height: var(--markdown-h5-line-height);
--markdown-h6-font-size: var(--text-markdown);
--markdown-h6-line-height: var(--markdown-h6-line-height);
--markdown-list-font-size: var(--text-markdown);
--markdown-list-line-height: var(--markdown-list-line-height);
--markdown-code-block-font-size: var(--text-code);
--markdown-code-block-line-height: var(--markdown-code-block-line-height);
/* Markdown color variables */
--markdown-heading1: var(--markdown-heading1);
--markdown-heading2: var(--markdown-heading2);
--markdown-heading3: var(--markdown-heading3);
--markdown-heading4: var(--markdown-heading4);
--markdown-link: var(--markdown-link);
--markdown-link-hover: var(--markdown-link-hover);
--markdown-list-marker: var(--markdown-list-marker);
--markdown-inline-code: var(--markdown-inline-code);
--markdown-inline-code-bg: var(--markdown-inline-code-bg);
--markdown-blockquote: var(--markdown-blockquote);
--markdown-blockquote-border: var(--markdown-blockquote-border);
/* Markdown spacing defaults */
--markdown-paragraph-spacing: 0.75rem;
--markdown-heading-primary-top: 0.75rem;
--markdown-heading-primary-bottom: 0.35rem;
--markdown-heading-secondary-top: 0.6rem;
--markdown-heading-secondary-bottom: 0.3rem;
--markdown-blockquote-spacing: 0.6rem;
--markdown-blockquote-padding: 0.75rem;
--markdown-divider-spacing: 0.85rem;
--markdown-table-spacing: 0.9rem;
--markdown-heading1-size: var(--text-markdown);
--markdown-heading2-size: var(--text-markdown);
--markdown-heading3-size: var(--text-markdown);
--markdown-heading4-size: var(--text-markdown);
--markdown-heading5-size: var(--text-markdown);
--markdown-heading6-size: var(--text-markdown);
--font-sans: "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
--font-heading: var(--font-sans);
--font-mono: ui-monospace, "SFMono-Regular", "Menlo", "Cascadia Mono", "Segoe UI Mono", monospace;
--font-family-sans: var(--font-sans);
--font-family-mono: var(--font-mono);
}
/* Agent color system using theme variables */
@layer components {
/* Agent color variants - each maps to theme colors */
.agent-primary {
--agent-color: var(--primary);
--agent-color-bg: var(--primary);
}
.agent-info {
--agent-color: var(--status-info);
--agent-color-bg: var(--status-info);
}
.agent-keyword {
--agent-color: var(--syntax-keyword);
--agent-color-bg: var(--syntax-keyword);
}
.agent-success {
--agent-color: var(--status-success);
--agent-color-bg: var(--status-success);
}
.agent-function {
--agent-color: var(--syntax-function);
--agent-color-bg: var(--syntax-function);
}
.agent-number {
--agent-color: var(--syntax-number);
--agent-color-bg: var(--syntax-number);
}
.agent-type {
--agent-color: var(--syntax-type);
--agent-color-bg: var(--syntax-type);
}
.agent-warning {
--agent-color: var(--status-warning);
--agent-color-bg: var(--status-warning);
}
.agent-variable {
--agent-color: var(--syntax-variable);
--agent-color-bg: var(--syntax-variable);
}
/* Apply colors with opacity for badges */
.agent-badge {
background: rgb(from var(--agent-color-bg) r g b / 0.1);
border: 1px solid rgb(from var(--agent-color) r g b / 0.2);
color: var(--agent-color);
}
.agent-badge:hover {
background: rgb(from var(--agent-color-bg) r g b / 0.15);
border-color: rgb(from var(--agent-color) r g b / 0.3);
}
/* Agent dot indicator */
.agent-dot {
background: var(--agent-color);
}
/* Agent list item */
.agent-list-item:hover {
background: rgb(from var(--agent-color-bg) r g b / 0.05);
}
.agent-list-item.active {
background: rgb(from var(--agent-color-bg) r g b / 0.1);
border-color: rgb(from var(--agent-color) r g b / 0.2);
}
}