@tailwind base; @tailwind components; @tailwind utilities; /** * CSS-based sidebar and panel widths to prevent SSR hydration mismatches. * Default widths are set here and updated via blocking script before React hydrates. * * @important These values must stay in sync with stores/constants.ts * @see stores/constants.ts for the source of truth */ :root { --sidebar-width: 232px; /* SIDEBAR_WIDTH.DEFAULT */ --panel-width: 320px; /* PANEL_WIDTH.DEFAULT */ --toolbar-triggers-height: 300px; /* TOOLBAR_TRIGGERS_HEIGHT.DEFAULT */ --editor-connections-height: 172px; /* EDITOR_CONNECTIONS_HEIGHT.DEFAULT */ --terminal-height: 206px; /* TERMINAL_HEIGHT.DEFAULT */ } .sidebar-container { width: var(--sidebar-width); } .panel-container { width: var(--panel-width); } .terminal-container { height: var(--terminal-height); } /** * Landing loop animation styles (keyframes defined in tailwind.config.ts) */ .landing-loop-animated-dash { animation: dash-animation 1.5s linear infinite; will-change: stroke-dashoffset; transform: translateZ(0); } .react-flow__node-landingLoop svg rect.landing-loop-animated-dash { animation: dash-animation 1.5s linear infinite !important; } /** * React Flow selection box styling * Uses brand-secondary color for selection highlighting */ .react-flow__selection { background: rgba(51, 180, 255, 0.08) !important; border: 1px solid var(--brand-secondary) !important; } .react-flow__nodesselection-rect, .react-flow__nodesselection { background: transparent !important; border: none !important; pointer-events: none !important; } /** * Workflow canvas cursor styles * Override React Flow's default selection cursor based on canvas mode */ .workflow-container.canvas-mode-cursor .react-flow__pane, .workflow-container.canvas-mode-cursor .react-flow__selectionpane { cursor: default !important; } .workflow-container.canvas-mode-hand .react-flow__pane, .workflow-container.canvas-mode-hand .react-flow__selectionpane { cursor: grab !important; } .workflow-container.canvas-mode-hand .react-flow__pane:active, .workflow-container.canvas-mode-hand .react-flow__selectionpane:active { cursor: grabbing !important; } /** * Color tokens - single source of truth for all colors * Light mode: Warm theme * Dark mode: Dark neutral theme */ @layer base { :root, .light { --bg: #fefefe; /* main canvas - neutral near-white */ --surface-1: #fefefe; /* sidebar, panels */ --surface-2: #ffffff; /* blocks, cards, modals - pure white */ --surface-3: #f7f7f7; /* popovers, headers */ --surface-4: #f5f5f5; /* buttons base */ --border: #e0e0e0; /* primary border */ --surface-5: #f3f3f3; /* inputs, form elements */ --border-1: #e0e0e0; /* stronger border */ --surface-6: #f0f0f0; /* popovers, elevated surfaces */ --surface-7: #ececec; --workflow-edge: #e0e0e0; /* workflow handles/edges - matches border-1 */ /* Text - neutral */ --text-primary: #2d2d2d; --text-secondary: #404040; --text-tertiary: #5c5c5c; --text-muted: #737373; --text-subtle: #8c8c8c; --text-inverse: #ffffff; --text-muted-inverse: #a0a0a0; --text-error: #ef4444; /* Borders / dividers */ --divider: #ededed; --border-muted: #e4e4e4; --border-success: #e0e0e0; /* Brand & state */ --brand-400: #8e4cfb; --brand-secondary: #33b4ff; --brand-tertiary: #22c55e; --brand-tertiary-2: #32bd7e; --warning: #ea580c; /* Utility */ --white: #ffffff; /* Font weights - lighter for light mode */ --font-weight-base: 430; --font-weight-medium: 450; --font-weight-semibold: 500; /* Extended palette */ --c-0D0D0D: #0d0d0d; --c-1A1A1A: #1a1a1a; --c-1F1F1F: #1f1f1f; --c-2A2A2A: #2a2a2a; --c-383838: #383838; --c-414141: #414141; --c-442929: #442929; --c-491515: #491515; --c-575757: #575757; --c-686868: #686868; --c-707070: #707070; --c-727272: #727272; --c-737373: #737373; --c-808080: #808080; --c-858585: #858585; --c-868686: #868686; --c-8D8D8D: #8d8d8d; --c-939393: #939393; --c-A8A8A8: #a8a8a8; --c-B8B8B8: #b8b8b8; --c-C0C0C0: #c0c0c0; --c-CDCDCD: #cdcdcd; --c-D0D0D0: #d0d0d0; --c-D2D2D2: #d2d2d2; --c-E0E0E0: #e0e0e0; --c-E5E5E5: #e5e5e5; --c-E8E8E8: #e8e8e8; --c-EEEEEE: #eeeeee; --c-F0F0F0: #f0f0f0; --c-F4F4F4: #f4f4f4; --c-F5F5F5: #f5f5f5; /* Blues and cyans */ --c-00B0B0: #00b0b0; --c-264F78: #264f78; --c-2F55FF: #2f55ff; --c-2FA1FF: #2fa1ff; --c-336699: #336699; --c-34B5FF: #34b5ff; --c-601EE0: #601ee0; --c-611F69: #611f69; --c-802FFF: #802fff; --c-8357FF: #8357ff; --c-8C10FF: #8c10ff; /* Greens */ --c-4CAF50: #22c55e; /* Oranges / Ambers */ --c-F59E0B: #f59e0b; --c-F97316: #ea580c; --c-FF972F: #f97316; /* Reds */ --c-DC2626: #dc2626; --c-F6D2D2: #fecaca; --c-F87171: #f87171; --c-FF402F: #ef4444; --c-B91C1C: #b91c1c; --c-883827: #7c2d12; /* Terminal status badges */ --terminal-status-error-bg: #fef2f2; --terminal-status-error-border: #f87171; --terminal-status-info-bg: #f7f7f7; --terminal-status-info-border: #a3a3a3; --terminal-status-info-color: #525252; --terminal-status-warning-bg: #fefce8; --terminal-status-warning-border: #facc15; --terminal-status-warning-color: #a16207; } .dark { /* Surface */ --bg: #1b1b1b; --surface-1: #1e1e1e; --surface-2: #232323; --surface-3: #242424; --surface-4: #292929; --border: #2c2c2c; --surface-5: #363636; --border-1: #3d3d3d; --surface-6: #454545; --surface-7: #454545; --workflow-edge: #454545; /* workflow handles/edges - same as surface-6 in dark */ /* Text */ --text-primary: #e6e6e6; --text-secondary: #cccccc; --text-tertiary: #b3b3b3; --text-muted: #787878; --text-subtle: #7d7d7d; --text-inverse: #1b1b1b; --text-muted-inverse: #b3b3b3; --text-error: #ef4444; /* --border-strong: #303030; */ --divider: #393939; --border-muted: #424242; --border-success: #575757; /* Brand & state */ --brand-400: #8e4cfb; --brand-secondary: #33b4ff; --brand-tertiary: #22c55e; --brand-tertiary-2: #32bd7e; --warning: #ff6600; /* Utility */ --white: #ffffff; /* Font weights - standard weights for dark mode */ --font-weight-base: 440; --font-weight-medium: 480; --font-weight-semibold: 550; /* Extended palette (exhaustive from code usage via -[#...]) */ /* Neutral deep shades */ --c-0D0D0D: #0d0d0d; --c-1A1A1A: #1a1a1a; --c-1F1F1F: #1f1f1f; --c-2A2A2A: #2a2a2a; --c-383838: #383838; --c-414141: #414141; --c-442929: #442929; --c-491515: #491515; --c-575757: #575757; --c-686868: #686868; --c-707070: #707070; --c-727272: #727272; --c-737373: #737373; --c-808080: #808080; --c-858585: #858585; --c-868686: #868686; --c-8D8D8D: #8d8d8d; --c-939393: #939393; --c-A8A8A8: #a8a8a8; --c-B8B8B8: #b8b8b8; --c-C0C0C0: #c0c0c0; --c-CDCDCD: #cdcdcd; --c-D0D0D0: #d0d0d0; --c-D2D2D2: #d2d2d2; --c-E0E0E0: #e0e0e0; --c-E5E5E5: #e5e5e5; --c-E8E8E8: #e8e8e8; --c-EEEEEE: #eeeeee; --c-F0F0F0: #f0f0f0; --c-F4F4F4: #f4f4f4; --c-F5F5F5: #f5f5f5; --c-CFCFCF: #cfcfcf; /* Blues and cyans */ --c-00B0B0: #00b0b0; --c-264F78: #264f78; --c-2F55FF: #2f55ff; --c-2FA1FF: #2fa1ff; --c-336699: #336699; --c-34B5FF: #34b5ff; --c-601EE0: #601ee0; --c-611F69: #611f69; --c-802FFF: #802fff; --c-8357FF: #8357ff; --c-8C10FF: #8c10ff; /* Greens */ --c-4CAF50: #4caf50; /* Oranges / Ambers */ --c-F59E0B: #f59e0b; --c-F97316: #f97316; --c-FF972F: #ff972f; /* Reds */ --c-DC2626: #dc2626; --c-F6D2D2: #f6d2d2; --c-F87171: #f87171; --c-FF402F: #ff402f; --c-B91C1C: #b91c1c; --c-883827: #883827; /* Terminal status badges */ --terminal-status-error-bg: #491515; --terminal-status-error-border: #883827; --terminal-status-info-bg: #383838; --terminal-status-info-border: #686868; --terminal-status-info-color: #b7b7b7; --terminal-status-warning-bg: #3d3520; --terminal-status-warning-border: #5c4d1f; --terminal-status-warning-color: #d4a72c; } } /** * Base styles for body, scrollbars, and global elements */ @layer base { * { border-color: var(--border); overscroll-behavior-x: none; } *:focus { outline: none; } body { background-color: var(--bg); color: var(--text-primary); overscroll-behavior-x: none; overscroll-behavior-y: none; min-height: 100vh; scrollbar-gutter: stable; text-rendering: optimizeSpeed; letter-spacing: 0.28px; } /* Ensure visible text caret across inputs and editors */ input, textarea, [contenteditable="true"] { caret-color: var(--text-primary); } .dark input, .dark textarea, .dark [contenteditable="true"] { caret-color: var(--text-primary); } .dark body { @apply antialiased; } ::-webkit-scrollbar { width: var(--scrollbar-size); height: var(--scrollbar-size); } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background-color: #c0c0c0; border-radius: var(--radius); } ::-webkit-scrollbar-thumb:hover { background-color: #a8a8a8; } /* Dark Mode Global Scrollbar */ .dark ::-webkit-scrollbar-track { background: transparent; } .dark ::-webkit-scrollbar-thumb { background-color: #5a5a5a; } .dark ::-webkit-scrollbar-thumb:hover { background-color: #6a6a6a; } * { scrollbar-width: thin; scrollbar-color: #c0c0c0 transparent; } .dark * { scrollbar-color: #5a5a5a transparent; } .copilot-scrollable { scrollbar-gutter: stable; } } /** * Panel tab styles */ .panel-tab-base { color: var(--base-muted-foreground); } .panel-tab-active { background-color: var(--surface-5); color: var(--text-primary); border-color: var(--border-muted); } .dark .panel-tab-active { background-color: var(--surface-1); color: var(--white); border-color: var(--border-muted); } .panel-tab-inactive:hover { background-color: var(--surface-5); color: var(--text-primary); } /** * Subblock divider visibility * Hides dividers when adjacent subblocks render empty content (e.g., schedule-info without data). * Uses CSS :has() to detect empty .subblock-content elements and hide associated dividers. * Selectors ordered by ascending specificity: (0,4,0) then (0,5,0) */ .subblock-row:has(> .subblock-content:empty) > .subblock-divider, .subblock-row:has(+ .subblock-row > .subblock-content:empty) > .subblock-divider { display: none; } /** * Dark mode specific overrides */ .dark .bg-red-500 { @apply bg-red-700; } /** * Browser input overrides */ input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; } input[type="search"]::-moz-search-cancel-button { display: none; } input[type="search"]::-ms-clear { display: none; } /** * Utilities and special effects * Animation keyframes are defined in tailwind.config.ts */ @layer utilities { .scrollbar-none { -ms-overflow-style: none; scrollbar-width: none; } .scrollbar-none::-webkit-scrollbar { display: none; } .scrollbar-hide { -webkit-scrollbar: none; -webkit-scrollbar-width: none; -webkit-scrollbar-track: transparent; -webkit-scrollbar-thumb: transparent; scrollbar-width: none; scrollbar-color: transparent transparent; -ms-overflow-style: none; } .scrollbar-hide::-webkit-scrollbar { display: none; width: 0; height: 0; background: transparent; } .scrollbar-hide::-webkit-scrollbar-track { display: none; background: transparent; } .scrollbar-hide::-webkit-scrollbar-thumb { display: none; background: transparent; } .gradient-text { -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .bg-input-background { background-color: hsl(var(--input-background)); } .auth-card { background-color: var(--white) !important; border-color: var(--border-muted) !important; } .dark .auth-card { background-color: var(--surface-1) !important; border-color: var(--border-muted) !important; } .auth-text-primary { color: var(--text-inverse) !important; } .auth-text-secondary { color: var(--text-secondary) !important; } .auth-text-muted { color: var(--text-muted) !important; } .auth-divider { border-color: var(--border-muted) !important; } .auth-card-shadow { box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.05), 0 4px 6px -2px rgba(0, 0, 0, 0.05) !important; } .auth-link { color: var(--text-muted) !important; } .transition-ring { transition-property: box-shadow, transform; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 300ms; } .loading-placeholder::placeholder { animation: placeholder-pulse 1.5s ease-in-out infinite; } .branded-button-gradient { background: linear-gradient(to bottom, #8357ff, #6f3dfa) !important; border-color: #6f3dfa !important; box-shadow: inset 0 2px 4px 0 #9b77ff !important; } .branded-button-gradient:hover { background: linear-gradient(to bottom, #8357ff, #6f3dfa) !important; opacity: 0.9; } .branded-button-custom { background: var(--brand-primary-hex) !important; border-color: var(--brand-primary-hex) !important; } .branded-button-custom:hover { background: var(--brand-primary-hover-hex) !important; border-color: var(--brand-primary-hover-hex) !important; } /** * Panel tab visibility and styling to prevent hydration flash */ html[data-panel-active-tab="copilot"] .panel-container [data-tab-content="toolbar"], html[data-panel-active-tab="copilot"] .panel-container [data-tab-content="editor"] { display: none !important; } html[data-panel-active-tab="toolbar"] .panel-container [data-tab-content="copilot"], html[data-panel-active-tab="toolbar"] .panel-container [data-tab-content="editor"] { display: none !important; } html[data-panel-active-tab="editor"] .panel-container [data-tab-content="copilot"], html[data-panel-active-tab="editor"] .panel-container [data-tab-content="toolbar"] { display: none !important; } html[data-panel-active-tab="copilot"] .panel-container [data-tab-button="copilot"] { background-color: var(--border-1) !important; color: var(--text-primary) !important; } html[data-panel-active-tab="copilot"] .panel-container [data-tab-button="toolbar"], html[data-panel-active-tab="copilot"] .panel-container [data-tab-button="editor"] { background-color: transparent !important; color: var(--text-tertiary) !important; } html[data-panel-active-tab="toolbar"] .panel-container [data-tab-button="toolbar"] { background-color: var(--border-1) !important; color: var(--text-primary) !important; } html[data-panel-active-tab="toolbar"] .panel-container [data-tab-button="copilot"], html[data-panel-active-tab="toolbar"] .panel-container [data-tab-button="editor"] { background-color: transparent !important; color: var(--text-tertiary) !important; } html[data-panel-active-tab="editor"] .panel-container [data-tab-button="editor"] { background-color: var(--border-1) !important; color: var(--text-primary) !important; } html[data-panel-active-tab="editor"] .panel-container [data-tab-button="copilot"], html[data-panel-active-tab="editor"] .panel-container [data-tab-button="toolbar"] { background-color: transparent !important; color: var(--text-tertiary) !important; } } /** * Notification toast enter animation */ @keyframes notification-enter { from { opacity: 0; transform: translateX(-16px); } to { opacity: 1; transform: translateX(var(--stack-offset, 0px)); } } /** * @depricated * Legacy globals (light/dark) kept for backward-compat with old classes. * Do not modify; remove after migration. */ @layer base { :root, .light { --background: 0 0% 100%; --foreground: 0 0% 3.9%; --card: 0 0% 99.2%; --card-foreground: 0 0% 3.9%; --popover: 0 0% 100%; --popover-foreground: 0 0% 3.9%; --primary: 0 0% 11.2%; --primary-foreground: 0 0% 98%; --secondary: 0 0% 96.1%; --secondary-foreground: 0 0% 11.2%; --muted: 0 0% 96.1%; --muted-foreground: 0 0% 46.9%; --accent: 0 0% 92.5%; --accent-foreground: 0 0% 11.2%; --destructive: 0 84.2% 60.2%; --destructive-foreground: 0 0% 98%; --input: 0 0% 89.8%; --input-background: 0 0% 100%; --ring: 0 0% 3.9%; --radius: 0.5rem; --scrollbar-track: 0 0% 85%; --scrollbar-thumb: 0 0% 65%; --scrollbar-thumb-hover: 0 0% 55%; --scrollbar-size: 8px; --workflow-background: 0 0% 100%; --card-background: 0 0% 99.2%; --card-border: 0 0% 89.8%; --card-text: 0 0% 3.9%; --card-hover: 0 0% 96.1%; --base-muted-foreground: #737373; --gradient-primary: 263 85% 70%; --gradient-secondary: 336 95% 65%; --brand-primary-hex: #6f3dfa; --brand-primary-hover-hex: #6338d9; --brand-accent-hex: #6f3dfa; --brand-accent-hover-hex: #6f3dfa; --brand-background-hex: #ffffff; --surface-elevated: #202020; } .dark { --background: 0 0% 10.59%; --foreground: 0 0% 98%; --card: 0 0% 9.0%; --card-foreground: 0 0% 98%; --popover: 0 0% 9.0%; --popover-foreground: 0 0% 98%; --primary: 0 0% 11.2%; --primary-foreground: 0 0% 98%; --secondary: 0 0% 12.0%; --secondary-foreground: 0 0% 98%; --muted: 0 0% 17.5%; /* --muted-foreground: 0 0% 65.1%; */ --accent: 0 0% 17.5%; --accent-foreground: 0 0% 98%; --destructive: 0 62.8% 30.6%; --destructive-foreground: 0 0% 98%; --input: 0 0% 16.1%; --input-background: 0 0% 20.78%; --ring: 0 0% 83.9%; --scrollbar-track: 0 0% 17.5%; --scrollbar-thumb: 0 0% 30%; --scrollbar-thumb-hover: 0 0% 40%; --workflow-background: 0 0% 10.59%; --card-background: 0 0% 9.0%; --card-border: 0 0% 22.7%; --card-text: 0 0% 98%; --card-hover: 0 0% 12.0%; --base-muted-foreground: #a3a3a3; --gradient-primary: 263 90% 75%; --gradient-secondary: 336 100% 72%; --brand-primary-hex: #701ffc; --brand-primary-hover-hex: #802fff; --brand-accent-hex: #9d54ff; --brand-accent-hover-hex: #a66fff; --brand-background-hex: #0c0c0c; --surface-elevated: #202020; } } /** * Remove backticks from inline code in prose (Tailwind Typography default) */ .prose code::before, .prose code::after { content: none !important; } /** * Remove underlines from heading anchor links in prose */ .prose h1 a, .prose h2 a, .prose h3 a, .prose h4 a, .prose h5 a, .prose h6 a { text-decoration: none !important; color: inherit !important; }