iris-gantt 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +279 -0
- package/dist/iris-gantt.css +1 -0
- package/dist/iris-gantt.js +3048 -0
- package/dist/iris-gantt.umd.cjs +23 -0
- package/dist/vite.svg +1 -0
- package/package.json +59 -0
- package/src/components/Gantt/gantt.css +2167 -0
package/README.md
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# SVAR Gantt Chart - Complete React Implementation
|
|
2
|
+
|
|
3
|
+
A comprehensive, production-ready Gantt chart component built with React and TypeScript, featuring all FREE and PRO capabilities from SVAR Gantt in a single, unified component.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
## ✨ Features
|
|
11
|
+
|
|
12
|
+
### 🎯 Core Features
|
|
13
|
+
- ✅ **Multi-column Task Grid** - Name, dates, duration, progress
|
|
14
|
+
- ✅ **Hierarchical Structure** - Parent/child tasks with expand/collapse
|
|
15
|
+
- ✅ **Configurable Timeline** - Hour/day/week/month/quarter/year scales
|
|
16
|
+
- ✅ **Zoom Controls** - In, out, reset with smooth transitions
|
|
17
|
+
- ✅ **Synchronized Scrolling** - Grid and timeline stay in sync
|
|
18
|
+
- ✅ **Weekend & Holiday Highlighting** - Visual differentiation
|
|
19
|
+
- ✅ **Light & Dark Themes** - Professional styling
|
|
20
|
+
|
|
21
|
+
### 🎨 Interactive Features
|
|
22
|
+
- ✅ **Drag & Drop** - Move tasks by dragging bars
|
|
23
|
+
- ✅ **Task Resize** - Adjust start/end dates from edges
|
|
24
|
+
- ✅ **Dependencies** - 4 types with curved arrows (e2s, s2s, e2e, s2e)
|
|
25
|
+
- ✅ **Progress Tracking** - Visual indicators on bars
|
|
26
|
+
- ✅ **Task Types** - Regular tasks, milestones, projects
|
|
27
|
+
- ✅ **Color Coding** - Custom colors per task
|
|
28
|
+
|
|
29
|
+
### 💎 PRO Features
|
|
30
|
+
- ✅ **Undo/Redo System** - 50-action history with Ctrl+Z/Y
|
|
31
|
+
- ✅ **Critical Path Analysis** - Automatic calculation and highlighting
|
|
32
|
+
- ✅ **Auto-Scheduling** - Forward/backward scheduling modes
|
|
33
|
+
- ✅ **Baselines** - Visual variance tracking with purple bars
|
|
34
|
+
- ✅ **Resource Leveling** - Prevent overallocation
|
|
35
|
+
- ✅ **Task Creation UI** - Beautiful modal form
|
|
36
|
+
- ✅ **Task Editing UI** - Double-click to edit
|
|
37
|
+
- ✅ **Advanced Filtering** - By status, priority, owner
|
|
38
|
+
- ✅ **Search** - Real-time across all fields
|
|
39
|
+
- ✅ **Export** - CSV, Excel, JSON, PDF
|
|
40
|
+
|
|
41
|
+
## 🚀 Quick Start
|
|
42
|
+
|
|
43
|
+
### Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Run Storybook
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm run storybook
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Or use the helper script:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
./run-storybook.sh
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Visit http://localhost:6006 to see all demos!
|
|
62
|
+
|
|
63
|
+
## 📖 Usage
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { Gantt } from './components/Gantt';
|
|
67
|
+
import type { Task, Link } from './components/types';
|
|
68
|
+
|
|
69
|
+
const tasks: Task[] = [
|
|
70
|
+
{
|
|
71
|
+
id: '1',
|
|
72
|
+
text: 'Project Planning',
|
|
73
|
+
start: new Date(2024, 0, 1),
|
|
74
|
+
end: new Date(2024, 0, 15),
|
|
75
|
+
duration: 14,
|
|
76
|
+
progress: 100,
|
|
77
|
+
type: 'project',
|
|
78
|
+
owner: 'John Smith',
|
|
79
|
+
priority: 'high',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: '2',
|
|
83
|
+
text: 'Development',
|
|
84
|
+
start: new Date(2024, 0, 15),
|
|
85
|
+
end: new Date(2024, 1, 15),
|
|
86
|
+
duration: 31,
|
|
87
|
+
progress: 60,
|
|
88
|
+
owner: 'Jane Doe',
|
|
89
|
+
priority: 'high',
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
const links: Link[] = [
|
|
94
|
+
{ id: 'l1', source: '1', target: '2', type: 'e2s' },
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
function App() {
|
|
98
|
+
return (
|
|
99
|
+
<Gantt
|
|
100
|
+
tasks={tasks}
|
|
101
|
+
links={links}
|
|
102
|
+
config={{
|
|
103
|
+
weekends: true,
|
|
104
|
+
theme: 'light',
|
|
105
|
+
}}
|
|
106
|
+
onTaskUpdate={(task) => console.log('Updated:', task)}
|
|
107
|
+
onTaskCreate={(task) => console.log('Created:', task)}
|
|
108
|
+
onTaskDelete={(id) => console.log('Deleted:', id)}
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## 🎨 Storybook Demos
|
|
115
|
+
|
|
116
|
+
The project includes comprehensive Storybook demos:
|
|
117
|
+
|
|
118
|
+
- **Gantt Chart/Basic Examples** - Simple projects and use cases
|
|
119
|
+
- **Gantt Chart/Advanced Features** - All PRO features in action
|
|
120
|
+
- **Gantt Chart/Baselines** - Baseline tracking demonstrations
|
|
121
|
+
|
|
122
|
+
## 🛠️ Configuration
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
interface GanttConfig {
|
|
126
|
+
columns?: Column[]; // Custom columns
|
|
127
|
+
scales?: Scale[]; // Timeline scales
|
|
128
|
+
readonly?: boolean; // Disable editing
|
|
129
|
+
editable?: boolean; // Enable inline editing
|
|
130
|
+
taskHeight?: number; // Task bar height
|
|
131
|
+
rowHeight?: number; // Row height
|
|
132
|
+
columnWidth?: number; // Timeline column width
|
|
133
|
+
weekends?: boolean; // Highlight weekends
|
|
134
|
+
holidays?: Date[]; // Holiday dates
|
|
135
|
+
theme?: 'light' | 'dark'; // Theme
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 🎯 Interactive Controls
|
|
140
|
+
|
|
141
|
+
### Toolbar Buttons
|
|
142
|
+
- **+ Add Task** - Create new tasks
|
|
143
|
+
- **↶ Undo / ↷ Redo** - Undo/redo with Ctrl+Z/Y
|
|
144
|
+
- **⚡ Auto-Schedule** - Auto-schedule based on dependencies
|
|
145
|
+
- **📊 Level Resources** - Balance workload
|
|
146
|
+
- **🎯 Critical Path** - Highlight critical tasks
|
|
147
|
+
- **📍 Baselines** - Create and toggle baselines
|
|
148
|
+
- **🔍 Zoom** - Zoom in/out/reset
|
|
149
|
+
- **💾 Export** - CSV, Excel, JSON, PDF
|
|
150
|
+
|
|
151
|
+
### Keyboard Shortcuts
|
|
152
|
+
- **Ctrl+Z** - Undo
|
|
153
|
+
- **Ctrl+Y** or **Ctrl+Shift+Z** - Redo
|
|
154
|
+
- **Double-click task** - Edit task
|
|
155
|
+
|
|
156
|
+
### Mouse Actions
|
|
157
|
+
- **Drag task bar** - Move task
|
|
158
|
+
- **Drag task edges** - Resize (adjust dates)
|
|
159
|
+
- **Click task** - Select
|
|
160
|
+
- **Hover dependencies** - Highlight relationships
|
|
161
|
+
|
|
162
|
+
## 📁 Project Structure
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
src/
|
|
166
|
+
├── components/
|
|
167
|
+
│ ├── Gantt/
|
|
168
|
+
│ │ ├── Gantt.tsx # Main unified component
|
|
169
|
+
│ │ ├── Grid.tsx # Task list grid
|
|
170
|
+
│ │ ├── Timeline.tsx # Timeline rendering
|
|
171
|
+
│ │ ├── TaskBar.tsx # Task visualization
|
|
172
|
+
│ │ ├── TaskCreator.tsx # Task creation modal
|
|
173
|
+
│ │ ├── TaskEditor.tsx # Task editing modal
|
|
174
|
+
│ │ ├── LinkRenderer.tsx # Dependency arrows
|
|
175
|
+
│ │ ├── DragDrop.tsx # Drag & drop logic
|
|
176
|
+
│ │ ├── FilterSearch.tsx # Filtering system
|
|
177
|
+
│ │ ├── UndoRedo.tsx # Undo/redo system
|
|
178
|
+
│ │ ├── CriticalPath.tsx # Critical path algorithm
|
|
179
|
+
│ │ ├── AutoScheduler.tsx # Auto-scheduling
|
|
180
|
+
│ │ ├── Baselines.tsx # Baseline tracking
|
|
181
|
+
│ │ ├── ExportUtils.tsx # Export functionality
|
|
182
|
+
│ │ └── gantt.css # All styles
|
|
183
|
+
│ ├── types.ts # TypeScript interfaces
|
|
184
|
+
│ └── utils/
|
|
185
|
+
│ └── dateUtils.ts # Date calculations
|
|
186
|
+
└── stories/
|
|
187
|
+
├── AdvancedGantt.stories.tsx # Basic examples
|
|
188
|
+
├── GanttProFeatures.stories.tsx # Advanced features
|
|
189
|
+
└── BaselinesDemo.stories.tsx # Baseline demos
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## 🎭 Task Types
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
interface Task {
|
|
196
|
+
id: string;
|
|
197
|
+
text: string;
|
|
198
|
+
start: Date;
|
|
199
|
+
end: Date;
|
|
200
|
+
duration: number;
|
|
201
|
+
progress: number;
|
|
202
|
+
type?: 'task' | 'milestone' | 'project';
|
|
203
|
+
parent?: string;
|
|
204
|
+
color?: string;
|
|
205
|
+
owner?: string;
|
|
206
|
+
priority?: 'low' | 'medium' | 'high';
|
|
207
|
+
details?: string;
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## 🔗 Dependency Types
|
|
212
|
+
|
|
213
|
+
- **e2s** (End-to-Start) - Task B starts when Task A ends
|
|
214
|
+
- **s2s** (Start-to-Start) - Tasks start together
|
|
215
|
+
- **e2e** (End-to-End) - Tasks end together
|
|
216
|
+
- **s2e** (Start-to-End) - Task B ends when Task A starts
|
|
217
|
+
|
|
218
|
+
## 🎨 Theming
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
<Gantt
|
|
222
|
+
tasks={tasks}
|
|
223
|
+
config={{ theme: 'dark' }} // or 'light'
|
|
224
|
+
/>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Custom colors can be applied per task:
|
|
228
|
+
```tsx
|
|
229
|
+
{
|
|
230
|
+
id: '1',
|
|
231
|
+
text: 'High Priority',
|
|
232
|
+
color: '#E74C3C', // Red
|
|
233
|
+
// ...
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## 📊 Export Formats
|
|
238
|
+
|
|
239
|
+
- **CSV** - Simple comma-separated values
|
|
240
|
+
- **Excel** - .xls format with UTF-8 BOM
|
|
241
|
+
- **JSON** - Complete project data (can be imported)
|
|
242
|
+
- **PDF** - Text report (can be enhanced with jsPDF)
|
|
243
|
+
|
|
244
|
+
## 🤝 Comparison with SVAR Gantt
|
|
245
|
+
|
|
246
|
+
This implementation provides **ALL** features from both SVAR Free and PRO editions in a single component:
|
|
247
|
+
|
|
248
|
+
| Feature | SVAR Free | SVAR PRO | This Implementation |
|
|
249
|
+
|---------|-----------|----------|---------------------|
|
|
250
|
+
| Task Management | ✅ | ✅ | ✅ |
|
|
251
|
+
| Dependencies | ✅ | ✅ | ✅ |
|
|
252
|
+
| Drag & Drop | ✅ | ✅ | ✅ |
|
|
253
|
+
| Progress Tracking | ✅ | ✅ | ✅ |
|
|
254
|
+
| Undo/Redo | ❌ | ✅ | ✅ |
|
|
255
|
+
| Auto-Scheduling | ❌ | ✅ | ✅ |
|
|
256
|
+
| Critical Path | ❌ | ✅ | ✅ |
|
|
257
|
+
| Baselines | ❌ | ✅ | ✅ |
|
|
258
|
+
| Resource Leveling | ❌ | ✅ | ✅ |
|
|
259
|
+
| Export | ❌ | ✅ | ✅ |
|
|
260
|
+
| Filtering | ❌ | ✅ | ✅ |
|
|
261
|
+
|
|
262
|
+
## 📝 License
|
|
263
|
+
|
|
264
|
+
MIT - Free for commercial and personal use
|
|
265
|
+
|
|
266
|
+
## 🙏 Acknowledgments
|
|
267
|
+
|
|
268
|
+
- Inspired by [SVAR Gantt Chart](https://svar.dev/demos/react/gantt/)
|
|
269
|
+
- Built with React 19, TypeScript 5.9, and Storybook 10
|
|
270
|
+
|
|
271
|
+
## 🔗 Links
|
|
272
|
+
|
|
273
|
+
- [GitHub Repository](https://github.com/TimJerry725/ganttchart)
|
|
274
|
+
- [Documentation](./GANTT_FEATURES.md)
|
|
275
|
+
- [Storybook Demos](http://localhost:6006)
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
**Made with ❤️ using React + TypeScript**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--wx-gantt-primary: #37a9ef;--wx-gantt-primary-selected: #d5eaf7;--wx-gantt-success: #77d257;--wx-gantt-warning: #fcba2e;--wx-gantt-danger: #fe6158;--wx-gantt-font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;--gantt-header-height: 84px;--gantt-row-height: 44px;--gantt-scale-height: 28px;--wx-gantt-border: 1px solid #e6e6e6;--wx-gantt-border-color: #e6e6e6;--wx-gantt-background: #ffffff;--wx-gantt-background-alt: #f2f3f7;--wx-gantt-background-hover: #eaedf5;--wx-gantt-select-color: #eaedf5;--wx-gantt-task-color: #37a9ef;--wx-gantt-task-fill-color: rgba(0, 0, 0, .15);--wx-gantt-project-color: #81C784;--wx-gantt-milestone-color: #9c27b0;--wx-gantt-milestone-border-radius: 2px;--wx-gantt-bar-border-radius: 3px;--wx-gantt-bar-shadow: 0 1px 2px rgba(44, 47, 60, .06), 0 3px 10px rgba(44, 47, 60, .12);--wx-gantt-font-color: #2c2f3c;--wx-gantt-font-color-alt: #9fa1ae;--wx-gantt-icon-color: #9fa1ae;--font-body: var(--wx-gantt-font-family);--color-primary: var(--wx-gantt-task-color);--color-text-main: var(--wx-gantt-font-color)}.gantt-page-wrapper{display:flex;flex-direction:column;height:calc(100vh - 40px);width:100%}.gantt-container{display:flex;flex-direction:column;flex:1;min-height:0;min-width:0;max-width:100%;overflow:hidden;background-color:var(--wx-gantt-background);border:var(--wx-gantt-border);margin:0;border-radius:var(--wx-gantt-bar-border-radius)}.gantt-container.theme-dark{background-color:#1e1e1e;border-color:#333;color:#e0e0e0;box-shadow:0 4px 12px #0003}.gantt-layout{display:flex;flex:1;overflow-x:auto;overflow-y:auto;position:relative;background-color:#fafafa;scroll-behavior:smooth;min-height:0;min-width:0;width:100%}.theme-dark .gantt-layout{background-color:#1a1a1a}.gantt-grid{display:flex;flex-direction:column;width:720px;min-width:720px;max-width:720px;border-right:var(--wx-gantt-border);background-color:#fff;flex-shrink:0;position:sticky;left:0;z-index:100!important;box-shadow:2px 0 5px #0000000d;height:100%;align-self:flex-start}.theme-dark .gantt-grid{background-color:#252525;border-right-color:#333;box-shadow:2px 0 5px #0000001a}.gantt-grid-header{position:sticky;top:0;z-index:110!important;height:var(--gantt-header-height);display:flex;border-bottom:var(--wx-gantt-border);background-color:#fff;box-shadow:none}.theme-dark .gantt-grid-header{background-color:#2d2d2d;border-bottom-color:#444}.gantt-grid-header-cell{height:100%;padding:0 16px;font-weight:600;font-size:14px;font-family:var(--font-body);border-right:var(--wx-gantt-border);background-color:var(--wx-gantt-background);color:var(--wx-gantt-font-color);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;justify-content:flex-start;flex-shrink:0;text-transform:none;letter-spacing:0}.gantt-grid-header-cell:last-child{border-right:none}.theme-dark .gantt-grid-header-cell{border-right-color:#333;background-color:#2d2d2d;color:#a0a0a0}.gantt-grid-body{flex:1}.gantt-grid-row{display:flex;border-bottom:var(--wx-gantt-border);cursor:pointer;transition:background-color .2s cubic-bezier(.4,0,.2,1);background-color:var(--wx-gantt-background);height:var(--gantt-row-height);min-height:var(--gantt-row-height);max-height:var(--gantt-row-height)}.gantt-grid-row:hover{background-color:#f8fafc;border-left:2px solid var(--color-primary)}.theme-dark .gantt-grid-row{background-color:#252525;border-bottom-color:#333}.theme-dark .gantt-grid-row:hover{background-color:#2d2d2d}.gantt-grid-row.dragging-row,.gantt-grid-row.descendant-dragging-row{opacity:.3;background-color:#f8f9fa;pointer-events:none}.gantt-ghost-descendant-count{margin-left:8px;background:#2196f3;color:#fff;padding:2px 6px;border-radius:10px;font-size:11px;font-weight:400}.gantt-grid-row.ghost-row{transition:none!important}body.gantt-dragging{-webkit-user-select:none!important;user-select:none!important;cursor:grabbing!important}.gantt-drop-indicator{position:absolute;left:0;right:0;height:2px;background-color:#2196f3;z-index:10;pointer-events:none}.gantt-drop-indicator.above{top:-1px}.gantt-drop-indicator.below{bottom:-1px}.gantt-drop-indicator.inside{top:0;bottom:0;height:auto;background-color:#2196f31a;border:2px solid #2196F3}.gantt-grid-body{position:relative}.gantt-grid-row.selected{background-color:#eff6ff;border-left:3px solid var(--color-primary)}.theme-dark .gantt-grid-row.selected{background-color:#2b3a4a}.gantt-grid-cell{padding:0 12px;font-size:14px;border-right:var(--wx-gantt-border);display:flex;align-items:center;overflow:hidden;font-family:var(--font-body);color:var(--wx-gantt-font-color);white-space:nowrap;text-overflow:ellipsis;flex-shrink:0}.gantt-grid-cell:last-child{border-right:none}.theme-dark .gantt-grid-cell{border-right-color:#2d2d2d;color:#dee2e6}.gantt-grid-cell-text{display:flex;align-items:center;gap:8px;white-space:nowrap;overflow:hidden;width:100%;color:#1a1f23;font-weight:400}.gantt-row-drag-handle{cursor:grab;color:#adb5bd;font-size:14px;line-height:1;padding:0 4px;-webkit-user-select:none;user-select:none;opacity:0;transition:opacity .2s}.gantt-grid-row:hover .gantt-row-drag-handle{opacity:1}.gantt-dragging .gantt-row-drag-handle{cursor:grabbing!important;z-index:100}.gantt-tree-icon{width:16px;height:16px;display:flex;align-items:center;justify-content:center;font-size:10px;color:#666;cursor:pointer;-webkit-user-select:none;user-select:none;background-color:transparent;border:none}.gantt-tree-icon:hover{background-color:#efefef}.gantt-progress-cell{display:flex;align-items:center;gap:8px;width:100%}.gantt-progress-bar-bg{flex:1;height:16px;background-color:#e0e0e0;border-radius:8px;overflow:hidden;position:relative}.gantt-progress-bar-fill{height:100%;background:linear-gradient(90deg,#81c784,#a5d6a7);transition:width .3s}.gantt-progress-text{font-size:11px;color:#666;min-width:35px;text-align:right}.gantt-timeline-container{display:flex;flex-direction:column;background-color:#fff;flex-shrink:0;min-width:0;overflow:visible}.theme-dark .gantt-timeline-container{background-color:#1e1e1e}.gantt-timeline-header{position:sticky;top:0;z-index:30;background-color:var(--wx-gantt-background);border-bottom:var(--wx-gantt-border);height:var(--gantt-header-height);box-shadow:none;overflow:visible}.gantt-timeline-scale{display:flex;border-bottom:var(--wx-gantt-border);align-items:center;min-height:var(--gantt-scale-height);width:100%}.theme-dark .gantt-timeline-header{background-color:#1e1e1e;border-bottom-color:#444}.gantt-timeline-scale-month{height:var(--gantt-scale-height);background-color:var(--wx-gantt-background);font-weight:600;display:flex;align-items:center;justify-content:center;border-bottom:var(--wx-gantt-border);font-size:13px;color:var(--wx-gantt-font-color);text-transform:none;font-family:var(--font-body)}.theme-dark .gantt-timeline-scale-month{background-color:#2a2a2a;color:#adb5bd;border-bottom-color:#333}.gantt-timeline-scale-range{height:var(--gantt-scale-height);background-color:var(--wx-gantt-background);font-size:13px;font-weight:600;color:var(--wx-gantt-font-color);display:flex;align-items:center;justify-content:center;border-bottom:var(--wx-gantt-border);text-transform:none;letter-spacing:0;font-family:var(--font-body)}.theme-dark .gantt-timeline-scale-range{background-color:#1e1e1e;color:#888;border-bottom-color:#333}.gantt-timeline-scale-day{height:var(--gantt-scale-height);background-color:var(--wx-gantt-background);border-bottom:none;display:flex;align-items:center;justify-content:center;font-size:13px;color:var(--wx-gantt-font-color);font-weight:400;font-family:var(--font-body)}.theme-dark .gantt-timeline-scale-day{background-color:#1e1e1e;color:#dee2e6}.gantt-timeline-cell{flex-shrink:0;height:100%;display:flex;align-items:center;justify-content:center;border-right:var(--wx-gantt-border);font-size:13px;white-space:nowrap;padding:0 4px;color:var(--wx-gantt-font-color);font-family:var(--font-body);min-width:0;overflow:hidden;text-overflow:ellipsis}.theme-dark .gantt-timeline-cell{border-right-color:#444}.gantt-timeline-cell.weekend{background-color:#f8fafc}.theme-dark .gantt-timeline-cell.weekend{background-color:#2a2a2a}.gantt-timeline-cell.holiday{background-color:#fff8f0}.theme-dark .gantt-timeline-cell.holiday{background-color:#3a2a1a}.gantt-timeline-body{position:relative;min-height:0}.gantt-timeline-grid{display:flex;position:absolute;top:0;left:0;bottom:0;pointer-events:none;z-index:0}.gantt-timeline-grid-column{flex-shrink:0;border-right:1px solid #e5e7eb}.theme-dark .gantt-timeline-grid-column{border-right-color:#2d2d2d}.gantt-timeline-grid-column.weekend{background-color:#f8fafc}.theme-dark .gantt-timeline-grid-column.weekend{background-color:#252525}.gantt-timeline-grid-column.holiday{background-color:#fff8f0}.theme-dark .gantt-timeline-grid-column.holiday{background-color:#332a1a}.gantt-timeline-tasks{position:relative;z-index:1;display:flex;flex-direction:column}.gantt-links-layer{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:1;overflow:visible}.gantt-link{pointer-events:all;cursor:pointer;transition:all .2s ease}.gantt-link-line{transition:all .2s ease;stroke:#cbd5e0;stroke-width:1.5}.theme-dark .gantt-link-line{stroke:#4a5568}.gantt-link:hover .gantt-link-line{stroke-width:2;stroke:#a0aec0}.theme-dark .gantt-link:hover .gantt-link-line{stroke:#90caf9}.gantt-link-arrow{transition:all .2s ease;fill:#cbd5e0}.theme-dark .gantt-link-arrow{fill:#64b5f6}.gantt-link:hover .gantt-link-arrow{fill:#2196f3;filter:drop-shadow(0 2px 4px rgba(33,150,243,.4))}.theme-dark .gantt-link:hover .gantt-link-arrow{fill:#90caf9}.gantt-timeline-row{position:relative;width:100%;border-bottom:1px solid #e5e7eb;height:var(--gantt-row-height);min-height:var(--gantt-row-height);max-height:var(--gantt-row-height);flex-shrink:0}.theme-dark .gantt-timeline-row{border-bottom-color:#333}.gantt-task-bar{position:absolute;height:28px;top:50%;transform:translateY(-50%);border-radius:var(--wx-gantt-bar-border-radius);cursor:move;transition:box-shadow .2s,transform .1s;display:flex;align-items:center;overflow:visible;border:none;box-shadow:0 1px 3px #0000001a}.gantt-task-bar:hover{box-shadow:0 4px 12px #00000026;transform:translateY(-50%) scale(1.02);z-index:100!important;filter:brightness(1.05)}.gantt-task-bar.selected{box-shadow:0 0 0 2px #fff,0 0 0 4px var(--color-primary);z-index:10;border:2px solid var(--color-primary)}.gantt-task-bar.dragging{opacity:.85;cursor:grabbing;box-shadow:0 10px 20px #00000030,0 6px 6px #0000003b;transition:none}.gantt-task-bar.project{height:28px;border-radius:var(--wx-gantt-bar-border-radius);font-weight:600;background-color:var(--wx-gantt-project-color)!important}.gantt-task-bar.milestone{width:0!important;height:0!important;overflow:visible;border:none;background:none!important;box-shadow:none}.gantt-milestone-diamond{position:absolute;top:50%;left:50%;width:14px;height:14px;background-color:var(--wx-gantt-milestone-color);transform:translate(-50%,-50%) rotate(45deg);border-radius:var(--wx-gantt-milestone-border-radius);box-shadow:var(--wx-gantt-bar-shadow);z-index:2;cursor:pointer}.gantt-milestone-text{position:absolute;left:20px;top:50%;transform:translateY(-50%);white-space:nowrap;color:var(--wx-gantt-font-color);font-size:13px;font-weight:400;pointer-events:none;font-family:var(--font-body)}.gantt-task-progress{position:absolute;left:0;top:0;height:100%;background-color:var(--wx-gantt-task-fill-color);pointer-events:none;z-index:1;border-radius:inherit}.gantt-task-content{position:relative;z-index:2;padding:0 12px;color:#fff;font-size:12px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;text-shadow:0 1px 2px rgba(0,0,0,.25);font-family:var(--font-body);height:100%;display:flex;align-items:center}.milestone .gantt-task-content{overflow:visible}.gantt-task-text{display:block;overflow:hidden;text-overflow:ellipsis}.gantt-task-resize-handle{position:absolute;top:0;width:8px;height:100%;cursor:ew-resize;z-index:3}.gantt-task-resize-left{left:0}.gantt-task-resize-right{right:0}.gantt-task-resize-handle:hover{background-color:#ffffff4d}.gantt-toolbar-wrapper{background-color:#f8f9fa;border-bottom:1px solid #dfe3e6;padding:4px 0}.gantt-toolbar{padding:8px 20px;background-color:transparent;display:flex;justify-content:space-between;align-items:center;z-index:100}.theme-dark .gantt-toolbar{background-color:#252525;border-bottom-color:#333}.gantt-toolbar-left,.gantt-toolbar-right{display:flex;align-items:center}.gantt-tooltip{padding:8px 12px;max-width:250px}.gantt-tooltip-title{font-weight:600;font-size:14px;margin-bottom:4px;color:#fff}.gantt-tooltip-dates{font-size:12px;color:#ced4da;margin-bottom:4px}.gantt-tooltip-progress,.gantt-tooltip-owner{font-size:12px;color:#fff}.gantt-task-group{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none}.gantt-task-bar.segment{pointer-events:all;background:repeating-linear-gradient(45deg,transparent,transparent 10px,rgba(255,255,255,.1) 10px,rgba(255,255,255,.1) 20px);border:1px dashed rgba(255,255,255,.4)}.gantt-task-bar.segment:hover{transform:translateY(-50%) scale(1.05);box-shadow:0 4px 8px #0000004d}.gantt-layout::-webkit-scrollbar{width:8px;height:8px}.gantt-layout::-webkit-scrollbar-track{background:transparent}.gantt-layout::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:10px;border:2px solid #ffffff}.gantt-layout::-webkit-scrollbar-thumb:hover{background:#94a3b8}.theme-dark .gantt-layout::-webkit-scrollbar-track{background:transparent;border-color:transparent}.theme-dark .gantt-layout::-webkit-scrollbar-thumb{background:#4a5568;border-color:#1a1a1a}.theme-dark .gantt-layout::-webkit-scrollbar-thumb:hover{background:#718096}.gantt-modal-overlay{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:1000}.gantt-modal{background-color:#fff;border-radius:8px;box-shadow:0 4px 20px #0000004d;max-width:600px;width:90%;max-height:90vh;overflow:hidden;display:flex;flex-direction:column}.theme-dark .gantt-modal{background-color:#2d2d2d;color:#fff}.gantt-modal-header{padding:20px;border-bottom:1px solid #e0e0e0;display:flex;justify-content:space-between;align-items:center}.theme-dark .gantt-modal-header{border-bottom-color:#444}.gantt-modal-header h3{margin:0;font-size:20px;font-weight:600}.gantt-modal-close{background:none;border:none;font-size:24px;cursor:pointer;color:#666;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all .2s}.gantt-modal-close:hover{background-color:#f0f0f0;color:#333}.theme-dark .gantt-modal-close:hover{background-color:#3a3a3a;color:#fff}.gantt-modal-body{padding:20px;overflow-y:auto;flex:1}.gantt-form-row{margin-bottom:16px}.gantt-form-row label{display:block;margin-bottom:6px;font-weight:500;font-size:14px;color:#333}.theme-dark .gantt-form-row label{color:#ddd}.gantt-form-row input[type=text],.gantt-form-row input[type=date],.gantt-form-row input[type=number],.gantt-form-row select,.gantt-form-row textarea{width:100%;padding:10px 12px;border:1px solid #d1d5da;border-radius:6px;font-size:14px;font-family:inherit;transition:border-color .2s}.theme-dark .gantt-form-row input,.theme-dark .gantt-form-row select,.theme-dark .gantt-form-row textarea{background-color:#3a3a3a;border-color:#555;color:#fff}.gantt-form-row input:focus,.gantt-form-row select:focus,.gantt-form-row textarea:focus{outline:none;border-color:#2196f3}.gantt-form-row textarea{resize:vertical;min-height:80px}.gantt-form-row-group{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px}.gantt-progress-value{margin-left:10px;font-weight:600;color:#2196f3}.gantt-modal-footer{padding:16px 20px;border-top:1px solid #e0e0e0;display:flex;justify-content:space-between;align-items:center}.theme-dark .gantt-modal-footer{border-top-color:#444}.gantt-modal-footer-right{display:flex;gap:10px}.gantt-btn{padding:10px 20px;border:none;border-radius:6px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s}.gantt-btn-primary{background-color:#2196f3;color:#fff}.gantt-btn-primary:hover{background-color:#1976d2;box-shadow:0 2px 8px #2196f34d}.gantt-btn-secondary{background-color:#f0f0f0;color:#333}.theme-dark .gantt-btn-secondary{background-color:#3a3a3a;color:#fff}.gantt-btn-secondary:hover{background-color:#e0e0e0}.theme-dark .gantt-btn-secondary:hover{background-color:#4a4a4a}.gantt-btn-danger{background-color:#f44336;color:#fff}.gantt-btn-danger:hover{background-color:#d32f2f}.gantt-filter-container{background-color:#f8f9fa;border-bottom:1px solid #e0e0e0}.theme-dark .gantt-filter-container{background-color:#2a2a2a;border-bottom-color:#444}.gantt-filter-bar{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;gap:16px}.gantt-filter-left{display:flex;align-items:center;gap:10px}.gantt-filter-right{display:flex;align-items:center;gap:10px;margin-left:auto}.gantt-search-antd .ant-input-affix-wrapper{border-radius:6px;font-family:var(--font-body)}.gantt-filter-select-antd .ant-select-selector{border-radius:6px!important;font-family:var(--font-body)}.gantt-filter-clear-antd{border-radius:6px;font-family:var(--font-body);font-weight:500}.theme-dark .gantt-search-antd .ant-input-affix-wrapper,.theme-dark .gantt-filter-select-antd .ant-select-selector{background-color:#3a3a3a;border-color:#555;color:#fff}.theme-dark .gantt-search-antd .ant-input,.theme-dark .gantt-filter-select-antd .ant-select-selection-item{color:#fff}.theme-dark .gantt-search-antd .ant-input-prefix,.theme-dark .gantt-filter-select-antd .ant-select-arrow{color:#aaa}.gantt-task-bar.critical{background-color:#f44336!important;box-shadow:0 0 0 2px #f443364d}.gantt-task-bar.critical .gantt-task-progress{background-color:#fff6}.gantt-baseline-container{position:relative;width:100%;height:100%}.gantt-baseline-bar{position:absolute;height:8px;background-color:#bdbdbd;top:50%;transform:translateY(calc(-50% + 20px));border-radius:4px;z-index:0;pointer-events:none}.gantt-variance-indicator{position:absolute;height:2px;bottom:0;opacity:.5}.gantt-variance-indicator.delayed{background-color:#f44336}.gantt-variance-indicator.ahead{background-color:#4caf50}.gantt-variance-label{position:absolute;top:-18px;right:0;font-size:11px;font-weight:600;padding:2px 6px;border-radius:3px;background-color:#ffffffe6}.gantt-toolbar{display:flex;justify-content:space-between;align-items:center}.gantt-toolbar-left,.gantt-toolbar-right{display:flex;gap:8px;align-items:center}.gantt-toolbar button.active{background-color:#1976d2}.gantt-milestone-marker{width:14px;height:14px;background-color:#9c27b0;transform:rotate(45deg);margin:0 auto}.gantt-milestone-text{position:absolute;left:100%;top:50%;transform:translateY(-50%);margin-left:10px;white-space:nowrap;font-size:11px;color:#555;font-family:var(--font-body);pointer-events:none}.theme-dark .gantt-milestone-text{color:#ccc}.gantt-toolbar-separator{width:1px;height:24px;background-color:#ddd;margin:0 4px}.theme-dark .gantt-toolbar-separator{background-color:#555}.gantt-dependency-editor-overlay{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:10000;animation:fadeIn .2s ease-out}.gantt-dependency-editor{background:#fff;border-radius:8px;box-shadow:0 4px 20px #00000026;width:700px;max-width:90vw;max-height:90vh;overflow:hidden;display:flex;flex-direction:column;animation:slideUp .3s ease-out}.gantt-dependency-editor-header{display:flex;justify-content:space-between;align-items:center;padding:20px 24px;border-bottom:1px solid #e0e0e0;background-color:#f8f9fa}.gantt-dependency-editor-header h3{margin:0;font-size:18px;font-weight:600;color:#333}.gantt-dependency-editor-body{padding:24px;overflow-y:auto;flex:1}.gantt-dependency-section{margin-bottom:32px}.gantt-dependency-section h4{margin:0 0 12px;font-size:14px;font-weight:600;color:#555;text-transform:uppercase;letter-spacing:.5px}.gantt-dependency-section h5{margin:0 0 8px;font-size:13px;font-weight:600;color:#666}.gantt-empty-message{color:#999;font-style:italic;padding:12px;background-color:#f8f9fa;border-radius:4px;text-align:center}.gantt-dependency-list{list-style:none;padding:0;margin:0}.gantt-dependency-item{display:flex;justify-content:space-between;align-items:center;padding:12px;margin-bottom:8px;background-color:#f8f9fa;border-radius:6px;border:1px solid #e0e0e0;transition:all .2s}.gantt-dependency-item:hover{background-color:#e9ecef;border-color:#007bff}.gantt-dependency-info{display:flex;flex-direction:column;gap:4px;flex:1}.gantt-dependency-task-name{font-weight:500;color:#333;font-size:14px}.gantt-dependency-type{font-size:12px;color:#666;padding:2px 8px;background-color:#e3f2fd;border-radius:12px;display:inline-block;width:fit-content}.gantt-dependency-lag{font-size:11px;color:#ff9800;font-weight:600;padding:2px 6px;background-color:#fff3e0;border-radius:10px;display:inline-block;width:fit-content}.gantt-dependency-remove{background-color:transparent;border:none;font-size:16px;cursor:pointer;padding:4px 8px;border-radius:4px;transition:all .2s}.gantt-dependency-remove:hover{background-color:#ffebee}.gantt-add-dependency{border-top:2px dashed #dee2e6;padding-top:24px}.gantt-dependency-form{display:flex;flex-direction:column;gap:16px}.gantt-form-row{display:flex;flex-direction:column;gap:6px}.gantt-form-row label{font-size:13px;font-weight:500;color:#555;display:flex;flex-direction:column;gap:2px}.gantt-help-text{font-size:11px;color:#999;font-weight:400}.gantt-select,.gantt-input{padding:10px 12px;border:1px solid #ced4da;border-radius:6px;font-size:14px;font-family:inherit;transition:all .2s;background-color:#fff}.gantt-select:focus,.gantt-input:focus{outline:none;border-color:#007bff;box-shadow:0 0 0 3px #007bff1a}.gantt-form-actions{display:flex;gap:12px;margin-top:8px}.gantt-btn{padding:10px 20px;border:none;border-radius:6px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;font-family:inherit}.gantt-btn-primary{background-color:#007bff;color:#fff}.gantt-btn-primary:hover:not(:disabled){background-color:#0056b3;transform:translateY(-1px);box-shadow:0 2px 8px #007bff4d}.gantt-btn-primary:disabled{background-color:#ccc;cursor:not-allowed;opacity:.6}.gantt-dependency-help{background-color:#f8f9fa;border:1px solid #dee2e6;border-radius:8px;padding:16px;margin-top:24px}.gantt-dependency-help ul{margin:8px 0;padding-left:20px}.gantt-dependency-help li{margin-bottom:6px;font-size:13px;line-height:1.5;color:#555}.gantt-dependency-help strong{color:#333}.gantt-dependency-help code{background-color:#e9ecef;padding:2px 6px;border-radius:3px;font-family:var(--font-heading);font-size:12px;color:#d63384}.gantt-dependency-help p{margin:4px 0;font-size:13px;color:#666}.theme-dark .gantt-dependency-editor{background-color:#2d2d2d}.theme-dark .gantt-dependency-editor-header{background-color:#252525;border-bottom-color:#444}.theme-dark .gantt-dependency-editor-header h3{color:#e0e0e0}.theme-dark .gantt-empty-message{background-color:#252525;color:#888}.theme-dark .gantt-dependency-item{background-color:#252525;border-color:#444}.theme-dark .gantt-dependency-item:hover{background-color:#333;border-color:#007bff}.theme-dark .gantt-dependency-task-name{color:#e0e0e0}.theme-dark .gantt-dependency-type{background-color:#1a2332;color:#64b5f6}.theme-dark .gantt-dependency-help{background-color:#252525;border-color:#444}.theme-dark .gantt-dependency-help code{background-color:#333;color:#ff79c6}.theme-dark .gantt-select,.theme-dark .gantt-input{background-color:#333;border-color:#555;color:#e0e0e0}.theme-dark .gantt-dependency-section h4,.theme-dark .gantt-dependency-section h5,.theme-dark .gantt-form-row label{color:#b0b0b0}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}h1,h2,h3,h4,h5,h6,.gantt-toolbar button,.gantt-filter-label,.gantt-dependency-section h4,.gantt-dependency-section h5{font-family:var(--font-heading)}.gantt-grid-cell,.gantt-task-text,.gantt-dependency-task-name,.gantt-form-row label,.gantt-dependency-help p,.gantt-dependency-help li{font-family:var(--font-body)}.gantt-dependency-modal .ant-modal-header{font-family:var(--font-heading)}.gantt-dependency-modal .ant-modal-body,.gantt-dependency-modal .ant-list-item-meta-title{font-family:var(--font-body)}.gantt-dependency-modal .ant-typography{font-family:inherit}.gantt-dependency-modal code{font-family:var(--font-heading)}.gantt-dependency-modal .ant-btn,.gantt-dependency-modal .ant-select,.gantt-dependency-modal .ant-input-number{font-family:var(--font-body)}.gantt-context-menu-overlay{position:fixed;inset:0;z-index:9999;background:transparent}.gantt-context-menu{font-family:var(--font-body)}.gantt-context-menu .ant-menu{font-family:var(--font-body);min-width:180px}.gantt-context-menu .ant-menu-item{font-family:var(--font-body);font-size:13px;padding:8px 16px;height:auto;line-height:1.5}.gantt-context-menu .ant-menu-item-icon{margin-right:8px;font-size:14px}.theme-dark .gantt-context-menu .ant-menu{background-color:#2d2d2d;border-color:#444}.theme-dark .gantt-context-menu .ant-menu-item{color:#e0e0e0}.theme-dark .gantt-context-menu .ant-menu-item:hover{background-color:#3a3a3a;color:#fff}@media(max-width:1024px){.gantt-grid{min-width:250px;width:300px;max-width:40%}.gantt-toolbar,.gantt-toolbar-left,.gantt-toolbar-right{flex-wrap:wrap;gap:8px}.gantt-toolbar button{font-size:12px;padding:6px 12px}.gantt-toolbar button svg{margin-right:4px}}@media(max-width:768px){.gantt-page-wrapper{height:100vh;overflow:auto}.gantt-container{min-height:auto}.gantt-layout{flex-direction:column;height:auto;min-height:600px}.gantt-grid{min-width:100%;width:100%;max-width:100%;max-height:300px;border-right:none;border-bottom:2px solid #ddd}.gantt-timeline-container{flex:1;min-height:400px;overflow-x:auto;overflow-y:auto}.gantt-toolbar{padding:8px;flex-direction:column;align-items:stretch}.gantt-toolbar-left,.gantt-toolbar-right{width:100%;justify-content:flex-start;flex-wrap:wrap;gap:6px}.gantt-toolbar button{flex:1 1 auto;min-width:80px;font-size:11px;padding:8px 10px}.gantt-toolbar button svg{margin-right:4px;font-size:12px}.gantt-toolbar button{position:relative}.gantt-toolbar button svg{margin-right:0!important}.gantt-toolbar button:after{content:""}.gantt-filter-bar{flex-direction:column;gap:8px;padding:8px}.gantt-filter-left,.gantt-filter-right{width:100%;flex-direction:column;gap:8px}.gantt-search-antd,.gantt-filter-select-antd{width:100%!important}}@media(max-width:480px){.gantt-page-wrapper{height:100vh;overflow:auto}.gantt-toolbar{padding:6px}.gantt-toolbar button{font-size:10px;padding:6px 8px;min-width:60px}.gantt-toolbar button svg{font-size:11px;margin-right:2px}.gantt-toolbar button{display:inline-flex;align-items:center;justify-content:center;padding:8px!important;min-width:44px;position:relative}.gantt-toolbar button svg{margin-right:0!important;flex-shrink:0}.gantt-toolbar button{text-indent:-9999px;overflow:hidden;white-space:nowrap}.gantt-toolbar button svg{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);text-indent:0}.gantt-grid{max-height:250px}.gantt-grid-header-cell{padding:6px 8px;font-size:11px}.gantt-grid-cell{padding:6px 8px;font-size:12px}.gantt-timeline-container{min-height:350px}.gantt-timeline-cell{padding:6px 4px;font-size:11px;min-width:40px}.gantt-timeline-scale{font-size:10px}.gantt-dependency-modal .ant-modal{max-width:95vw!important;margin:10px auto!important}.gantt-dependency-editor{width:95vw!important;max-width:95vw!important}}@media(hover:none)and (pointer:coarse){.gantt-toolbar button{min-height:44px;min-width:44px;padding:10px 12px}.gantt-grid-row{min-height:48px}.gantt-grid-cell{padding:10px 12px}.gantt-timeline-cell{min-width:50px;padding:10px}}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){.gantt-grid,.gantt-timeline-container{border-width:.5px}}@media(max-width:768px)and (orientation:landscape){.gantt-layout{flex-direction:row}.gantt-grid{max-height:none;height:100%;width:500px;min-width:500px;max-width:500px}.gantt-timeline-container{min-height:auto;height:100%}}@media print{.gantt-toolbar,.gantt-filter-container{display:none}.gantt-layout{flex-direction:row}.gantt-grid{width:500px;max-width:500px;min-width:500px}.gantt-container,.gantt-grid,.gantt-timeline-container{overflow:visible}}@media(prefers-reduced-motion:reduce){.gantt-grid,.gantt-toolbar button,.gantt-grid-row,.gantt-progress-bar-fill{transition:none}}@media(max-width:768px){.gantt-timeline-header{overflow-x:auto;-webkit-overflow-scrolling:touch}.gantt-timeline-scale{min-width:max-content}.gantt-timeline-body{overflow-x:auto;-webkit-overflow-scrolling:touch}}.gantt-page-wrapper{position:relative;width:100%;max-width:100vw;overflow-x:hidden}.gantt-container{max-width:100%;overflow:hidden}.gantt-layout{max-width:100%;overflow-x:auto;overflow-y:auto}.dependency-popover .task-list-item{transition:background-color .2s ease,border-left .2s ease;border-left:3px solid transparent}.dependency-popover .task-list-item:hover{background-color:#f0f7ff!important;border-left-color:#1890ff}.dependency-popover .task-list-item.selected{background-color:#e6f4ff!important;border-left-color:#1890ff;font-weight:500}.dependency-popover .ant-list-item{border-bottom:1px solid #f0f0f0}.dependency-popover .ant-list-item:last-child{border-bottom:none}.gantt-dependency-modal .ant-modal-body{padding:24px}.gantt-dependency-modal .ant-card{box-shadow:0 1px 2px #00000008;border:1px solid #f0f0f0}.gantt-dependency-modal .ant-list-item{padding:12px 16px;transition:background-color .2s ease}.gantt-dependency-modal .ant-list-item:hover{background-color:#fafafa}.dependency-popover .ant-input:focus,.dependency-popover .ant-select-focused .ant-select-selector,.dependency-popover .ant-input-number-focused{border-color:#1890ff;box-shadow:0 0 0 2px #1890ff1a}.dependency-popover .ant-btn-primary{background-color:#5c67f2;border-color:#5c67f2;font-weight:500;transition:all .3s ease}.dependency-popover .ant-btn-primary:hover{background-color:#4854e0;border-color:#4854e0;transform:translateY(-1px);box-shadow:0 4px 12px #5c67f24d}.dependency-popover .ant-btn-primary:disabled{background-color:#f5f5f5;border-color:#d9d9d9;color:#00000040;transform:none;box-shadow:none}
|