@jaeungkim/gantt-chart 0.4.0 → 1.1.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.
Files changed (103) hide show
  1. package/README.md +60 -64
  2. package/dist/Gantt.d.ts +5 -0
  3. package/dist/bars/components/GanttBar.d.ts +20 -0
  4. package/dist/bars/components/GanttBarsLayer.d.ts +24 -0
  5. package/dist/bars/components/GanttDragGuides.d.ts +1 -0
  6. package/dist/bars/hooks/useGanttBarDrag.d.ts +16 -0
  7. package/dist/bars/hooks/useGanttDrawCreate.d.ts +25 -0
  8. package/dist/{hooks → bars/hooks}/useGanttProgressDrag.d.ts +3 -8
  9. package/dist/core/calendar.d.ts +4 -22
  10. package/dist/core/dates.d.ts +5 -21
  11. package/dist/core/index.d.ts +1 -14
  12. package/dist/core/reorder.d.ts +55 -0
  13. package/dist/core/tree.d.ts +4 -12
  14. package/dist/core/types.d.ts +4 -37
  15. package/dist/{components → dependencies/components}/GanttDependencyArrows.d.ts +4 -6
  16. package/dist/{hooks → dependencies/hooks}/useGanttLinkDrag.d.ts +2 -13
  17. package/dist/dependencies/utils/arrowPath.d.ts +20 -0
  18. package/dist/dependencies/utils/link.d.ts +17 -0
  19. package/dist/detail/components/GanttDetailPanel.d.ts +21 -0
  20. package/dist/detail/hooks/useGanttDetail.d.ts +42 -0
  21. package/dist/detail/utils/edit.d.ts +21 -0
  22. package/dist/gantt-chart.css +1 -1
  23. package/dist/index.cjs +1 -4
  24. package/dist/index.d.cts +11 -13
  25. package/dist/index.d.ts +11 -13
  26. package/dist/index.js +4071 -5141
  27. package/dist/interaction/hooks/useGanttInteraction.d.ts +2 -0
  28. package/dist/interaction/hooks/useGanttKeyboardNav.d.ts +33 -0
  29. package/dist/interaction/hooks/useGanttSelection.d.ts +12 -0
  30. package/dist/interaction/utils/a11y.d.ts +84 -0
  31. package/dist/props.d.ts +121 -0
  32. package/dist/rows/components/GanttRowsLayer.d.ts +13 -0
  33. package/dist/rows/hooks/useGanttCollapse.d.ts +18 -0
  34. package/dist/rows/hooks/useGanttRowModel.d.ts +19 -0
  35. package/dist/rows/utils/rows.d.ts +21 -0
  36. package/dist/shared/constants.d.ts +24 -0
  37. package/dist/{stores → shared}/context.d.ts +1 -7
  38. package/dist/shared/hooks/useLatestRef.d.ts +2 -0
  39. package/dist/shared/hooks/useResolvedTheme.d.ts +8 -0
  40. package/dist/shared/store.d.ts +81 -0
  41. package/dist/shared/task.d.ts +55 -0
  42. package/dist/shared/types.d.ts +115 -0
  43. package/dist/shared/utils/holidays.d.ts +12 -0
  44. package/dist/shared/utils/i18n.d.ts +5 -0
  45. package/dist/shared/utils/pointerGesture.d.ts +11 -0
  46. package/dist/shared/virtual/axis.d.ts +13 -0
  47. package/dist/shared/virtual/useVirtualWindow.d.ts +16 -0
  48. package/dist/shared/virtual/window.d.ts +30 -0
  49. package/dist/task-list/components/GanttGridSplitter.d.ts +6 -0
  50. package/dist/task-list/components/GanttTaskAddRow.d.ts +7 -0
  51. package/dist/task-list/components/GanttTaskGrid.d.ts +24 -0
  52. package/dist/task-list/hooks/useGanttRowDrag.d.ts +17 -0
  53. package/dist/task-list/hooks/useGanttTaskListPane.d.ts +11 -0
  54. package/dist/task-list/hooks/useGanttTaskMove.d.ts +16 -0
  55. package/dist/timeline/components/GanttChartHeader.d.ts +10 -0
  56. package/dist/timeline/components/GanttHolidayLabels.d.ts +6 -0
  57. package/dist/timeline/components/GanttNonWorkingLayer.d.ts +6 -0
  58. package/dist/timeline/components/GanttTodayLine.d.ts +6 -0
  59. package/dist/{hooks → timeline/hooks}/useGanttScrollApi.d.ts +22 -23
  60. package/dist/timeline/hooks/useGanttViewport.d.ts +47 -0
  61. package/dist/timeline/hooks/useGanttVirtualization.d.ts +28 -0
  62. package/dist/timeline/utils/geometry.d.ts +52 -0
  63. package/dist/timeline/utils/header.d.ts +8 -0
  64. package/dist/timeline/utils/transform.d.ts +4 -0
  65. package/dist/timeline/utils/viewport.d.ts +31 -0
  66. package/dist/useGanttSelectors.d.ts +11 -0
  67. package/package.json +12 -12
  68. package/dist/components/GanttBar.d.ts +0 -23
  69. package/dist/components/GanttChartHeader.d.ts +0 -17
  70. package/dist/components/GanttDragGuides.d.ts +0 -9
  71. package/dist/components/GanttGridSplitter.d.ts +0 -14
  72. package/dist/components/GanttMarkers.d.ts +0 -18
  73. package/dist/components/GanttTaskGrid.d.ts +0 -42
  74. package/dist/components/ScaleSelector.d.ts +0 -11
  75. package/dist/constants/gantt.d.ts +0 -47
  76. package/dist/core/criticalPath.d.ts +0 -67
  77. package/dist/core/scheduling.d.ts +0 -104
  78. package/dist/hooks/useGanttBarDrag.d.ts +0 -35
  79. package/dist/hooks/useGanttDrawCreate.d.ts +0 -31
  80. package/dist/hooks/useGanttExportApi.d.ts +0 -30
  81. package/dist/hooks/useGanttHistoryApi.d.ts +0 -28
  82. package/dist/hooks/useGanttRowDrag.d.ts +0 -33
  83. package/dist/hooks/useGanttSelectors.d.ts +0 -23
  84. package/dist/hooks/useGanttVirtualization.d.ts +0 -32
  85. package/dist/hooks/useResolvedTheme.d.ts +0 -15
  86. package/dist/pages/Gantt.d.ts +0 -306
  87. package/dist/stores/store.d.ts +0 -118
  88. package/dist/types/gantt.d.ts +0 -283
  89. package/dist/types/task.d.ts +0 -111
  90. package/dist/utils/a11y.d.ts +0 -141
  91. package/dist/utils/arrowPath.d.ts +0 -66
  92. package/dist/utils/dependency.d.ts +0 -42
  93. package/dist/utils/grouping.d.ts +0 -81
  94. package/dist/utils/headerUtils.d.ts +0 -6
  95. package/dist/utils/history.d.ts +0 -56
  96. package/dist/utils/i18n.d.ts +0 -16
  97. package/dist/utils/mutation.d.ts +0 -47
  98. package/dist/utils/pngExport.d.ts +0 -67
  99. package/dist/utils/pointerGesture.d.ts +0 -31
  100. package/dist/utils/rowDrag.d.ts +0 -69
  101. package/dist/utils/timeline.d.ts +0 -161
  102. package/dist/utils/transformData.d.ts +0 -15
  103. package/dist/utils/viewport.d.ts +0 -95
@@ -0,0 +1,17 @@
1
+ import { DependencyType, Task, TaskDependency, TaskTransformed } from '../../shared/task';
2
+ export type LinkAnchor = "start" | "end";
3
+ export type LinkRejection = "self" | "duplicate" | "cycle";
4
+ type DependencyNode = Pick<Task, "id"> & {
5
+ dependencies?: TaskDependency[];
6
+ };
7
+ export declare function linkTypeFromAnchors(from: LinkAnchor, to: LinkAnchor): DependencyType;
8
+ interface LinkTarget {
9
+ task: TaskTransformed;
10
+ anchor: LinkAnchor;
11
+ }
12
+ export declare function resolveLinkTarget(rowTasks: TaskTransformed[], contentX: number, contentY: number, rowHeight: number, zone: number): LinkTarget | null;
13
+ export declare function validateDependency(tasks: DependencyNode[], predecessorId: string, successorId: string): LinkRejection | null;
14
+ export declare const LINK_REJECTION_LABEL: Record<LinkRejection, string>;
15
+ export declare function addDependency(tasks: Task[], predecessorId: string, successorId: string, type: DependencyType): Task[];
16
+ export declare function removeDependency(tasks: Task[], predecessorId: string, successorId: string): Task[];
17
+ export {};
@@ -0,0 +1,21 @@
1
+ import { GanttDetailRenderer, GanttLocaleOptions, GanttScaleKey } from '../../shared/types';
2
+ import { GanttInteractionConfig, Task, TaskTransformed } from '../../shared/task';
3
+ interface GanttDetailPanelProps {
4
+ task: TaskTransformed;
5
+ /** Every task, so a dependency's target id can be printed by name */
6
+ tasks: TaskTransformed[];
7
+ scale: GanttScaleKey;
8
+ localeOptions?: GanttLocaleOptions;
9
+ /** Gates which built-in fields take input - the same flags the drag gestures obey */
10
+ interaction?: GanttInteractionConfig;
11
+ onClose: () => void;
12
+ onTasksChange?: (updatedTasks: Task[]) => void;
13
+ /** Replaces the body; the panel element itself, and its width, stay the chart's */
14
+ render?: GanttDetailRenderer;
15
+ /** False while the panel slides shut - the slide lives in flex-basis, see .gantt-detail */
16
+ open: boolean;
17
+ onTransitionEnd: React.TransitionEventHandler<HTMLElement>;
18
+ }
19
+ /** The docked panel on the right */
20
+ export default function GanttDetailPanel({ task, tasks, scale, localeOptions, interaction, onClose, onTasksChange, render, open, onTransitionEnd, }: GanttDetailPanelProps): import("react").JSX.Element;
21
+ export {};
@@ -0,0 +1,42 @@
1
+ import { TaskTransformed } from '../../shared/task';
2
+ type TaskMouseHandler = (task: TaskTransformed, event: React.MouseEvent) => void;
3
+ interface ResolvedDetailState<T extends {
4
+ id: string;
5
+ }> {
6
+ openId: string | null;
7
+ task: T | null;
8
+ stale: boolean;
9
+ }
10
+ export declare function resolveDetailState<T extends {
11
+ id: string;
12
+ }>({ enabled, detailTaskId, uncontrolled, tasks, }: {
13
+ enabled: boolean;
14
+ detailTaskId?: string | null;
15
+ uncontrolled: string | null;
16
+ tasks: T[];
17
+ }): ResolvedDetailState<T>;
18
+ interface UseGanttDetailParams {
19
+ enabled: boolean;
20
+ tasks: TaskTransformed[];
21
+ detailTaskId?: string | null;
22
+ onDetailChange?: (task: TaskTransformed | null) => void;
23
+ onTaskClick?: TaskMouseHandler;
24
+ }
25
+ interface GanttDetail {
26
+ task: TaskTransformed | null;
27
+ open: (taskId: string) => void;
28
+ close: () => void;
29
+ onTaskClick: TaskMouseHandler;
30
+ }
31
+ /** Controlled by `detailTaskId`, uncontrolled without it; `onDetailChange` fires in both modes */
32
+ export declare function useGanttDetail({ enabled, tasks, detailTaskId, onDetailChange, onTaskClick, }: UseGanttDetailParams): GanttDetail;
33
+ interface GanttDetailSlide {
34
+ /** The task to keep rendered - the open one, or the last one while the panel slides shut */
35
+ task: TaskTransformed | null;
36
+ /** Drives .gantt-detail-open - false on the mount frame so opening transitions up from zero */
37
+ open: boolean;
38
+ onTransitionEnd: React.TransitionEventHandler<HTMLElement>;
39
+ }
40
+ /** Holds the panel mounted through the slide-closed transition, then releases it */
41
+ export declare function useGanttDetailSlide(task: TaskTransformed | null): GanttDetailSlide;
42
+ export {};
@@ -0,0 +1,21 @@
1
+ import { GanttInteractionConfig, Task } from '../../shared/task';
2
+ export type DetailEditableField = "name" | "startDate" | "endDate" | "progress";
3
+ interface DetailEditability {
4
+ name: boolean;
5
+ /** One flag for both dates - changing either one is a resize */
6
+ dates: boolean;
7
+ progress: boolean;
8
+ }
9
+ export declare function resolveDetailEditability(task: Task & {
10
+ isSummary?: boolean;
11
+ }, config?: GanttInteractionConfig): DetailEditability;
12
+ /** Turns one field's raw input into a patch; null means the value cannot commit and the field reverts */
13
+ export declare function resolveFieldPatch(task: Task, field: DetailEditableField, value: string, config?: GanttInteractionConfig): Partial<Omit<Task, "id">> | null;
14
+ export declare function applyTaskPatch(rawTasks: Task[], taskId: string, patch: Partial<Omit<Task, "id">>): Task[];
15
+ export declare function commitDetailPatch(storeApi: {
16
+ getState: () => {
17
+ rawTasks: Task[];
18
+ setRawTasks: (tasks: Task[]) => void;
19
+ };
20
+ }, taskId: string, patch: Partial<Omit<Task, "id">>, onTasksChange?: (tasks: Task[]) => void): void;
21
+ export {};
@@ -1 +1 @@
1
- .gantt-container{--gantt-font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Geist", system-ui, sans-serif;--gantt-background: #fafafa;--gantt-foreground: #18181b;--gantt-muted: #f4f4f5;--gantt-muted-foreground: #71717a;--gantt-border: #e4e4e7;--gantt-border-subtle: rgba(0, 0, 0, .04);--gantt-bar-bg: #e4e4e7;--gantt-bar-bg-hover: #d4d4d8;--gantt-bar-text: #18181b;--gantt-bar-shadow: 0 1px 2px rgba(0, 0, 0, .05);--gantt-bar-shadow-hover: 0 4px 12px rgba(0, 0, 0, .1);--gantt-bar-shadow-drag: 0 8px 24px rgba(0, 0, 0, .15);--gantt-arrow: #a1a1aa;--gantt-accent: #3b82f6;--gantt-today-marker: #f43f5e;--gantt-marker: #6366f1;--gantt-marker-warning: #f59e0b;--gantt-marker-label: #ffffff;--gantt-band-bg: rgba(99, 102, 241, .1);--gantt-milestone-bg: #52525b;--gantt-milestone-bg-hover: #3f3f46;--gantt-critical: #dc2626;--gantt-critical-bg: #fecaca;--gantt-critical-bg-hover: #fca5a5;--gantt-critical-text: #7f1d1d;--gantt-baseline-bg: #a1a1aa;--gantt-progress-bg: #a1a1aa;--gantt-progress-handle: #52525b;--gantt-non-working-bg: rgba(0, 0, 0, .035);--gantt-duration-fast: .15s;--gantt-transition-fast: .15s ease;--gantt-transition-normal: .2s ease}.gantt-container.dark,.gantt-container[data-theme=dark]{--gantt-background: #09090b;--gantt-foreground: #fafafa;--gantt-muted: #18181b;--gantt-muted-foreground: #a1a1aa;--gantt-border: #27272a;--gantt-border-subtle: rgba(255, 255, 255, .04);--gantt-bar-bg: #27272a;--gantt-bar-bg-hover: #3f3f46;--gantt-bar-text: #fafafa;--gantt-bar-shadow: 0 1px 2px rgba(0, 0, 0, .2);--gantt-bar-shadow-hover: 0 4px 12px rgba(0, 0, 0, .3);--gantt-bar-shadow-drag: 0 8px 24px rgba(0, 0, 0, .4);--gantt-arrow: #71717a;--gantt-today-marker: #fb7185;--gantt-marker: #818cf8;--gantt-marker-warning: #fbbf24;--gantt-marker-label: #18181b;--gantt-band-bg: rgba(129, 140, 248, .16);--gantt-milestone-bg: #d4d4d8;--gantt-milestone-bg-hover: #e4e4e7;--gantt-critical: #f87171;--gantt-critical-bg: #7f1d1d;--gantt-critical-bg-hover: #991b1b;--gantt-critical-text: #fee2e2;--gantt-baseline-bg: #71717a;--gantt-progress-bg: #52525b;--gantt-progress-handle: #a1a1aa;--gantt-non-working-bg: rgba(255, 255, 255, .03)}@media(prefers-color-scheme:dark){.gantt-container:not(.light):not([data-theme=light]){--gantt-background: #09090b;--gantt-foreground: #fafafa;--gantt-muted: #18181b;--gantt-muted-foreground: #a1a1aa;--gantt-border: #27272a;--gantt-border-subtle: rgba(255, 255, 255, .04);--gantt-bar-bg: #27272a;--gantt-bar-bg-hover: #3f3f46;--gantt-bar-text: #fafafa;--gantt-bar-shadow: 0 1px 2px rgba(0, 0, 0, .2);--gantt-bar-shadow-hover: 0 4px 12px rgba(0, 0, 0, .3);--gantt-bar-shadow-drag: 0 8px 24px rgba(0, 0, 0, .4);--gantt-arrow: #71717a;--gantt-today-marker: #fb7185;--gantt-marker: #818cf8;--gantt-marker-warning: #fbbf24;--gantt-marker-label: #18181b;--gantt-band-bg: rgba(129, 140, 248, .16);--gantt-milestone-bg: #d4d4d8;--gantt-milestone-bg-hover: #e4e4e7;--gantt-critical: #f87171;--gantt-critical-bg: #7f1d1d;--gantt-critical-bg-hover: #991b1b;--gantt-critical-text: #fee2e2;--gantt-baseline-bg: #71717a;--gantt-progress-bg: #52525b;--gantt-progress-handle: #a1a1aa;--gantt-non-working-bg: rgba(255, 255, 255, .03)}}.gantt-container,.gantt-container *,.gantt-container *:before,.gantt-container *:after{box-sizing:border-box}.gantt-container{display:flex;flex-direction:column;overflow:hidden;background:var(--gantt-background);font-family:var(--gantt-font-sans);font-size:13px;line-height:1.5;color:var(--gantt-foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.gantt-container:focus{outline:none}.gantt-toolbar{flex-shrink:0;display:flex;align-items:center;justify-content:flex-end;padding:12px 16px;background:var(--gantt-background);border-bottom:1px solid var(--gantt-border)}.gantt-grid-toggle{margin-right:auto;display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;padding:0;color:var(--gantt-muted-foreground);background:transparent;border:1px solid var(--gantt-border);border-radius:6px;cursor:pointer;transition:color var(--gantt-transition-fast),background var(--gantt-transition-fast)}.gantt-grid-toggle:hover{color:var(--gantt-foreground);background:var(--gantt-muted)}.gantt-grid-toggle:focus-visible{outline:2px solid var(--gantt-accent);outline-offset:-2px}.gantt-grid-toggle svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.3}.gantt-grid-toggle[aria-expanded=true] svg rect{fill:var(--gantt-muted)}.gantt-scale-selector{display:inline-flex}.gantt-scale-control{display:flex;gap:2px;padding:3px;background:var(--gantt-muted);border-radius:8px;border:1px solid var(--gantt-border)}.gantt-scale-button{position:relative;padding:6px 14px;font-family:inherit;font-size:12px;font-weight:500;color:var(--gantt-muted-foreground);background:transparent;border:none;border-radius:6px;cursor:pointer;transition:all var(--gantt-transition-fast);text-transform:capitalize}.gantt-scale-button:hover{color:var(--gantt-foreground)}.gantt-scale-button:focus-visible{outline:2px solid var(--gantt-accent);outline-offset:-2px}.gantt-scale-button[data-active=true]{color:var(--gantt-foreground);background:var(--gantt-background);box-shadow:0 1px 3px #00000014}.gantt-main{position:relative;flex:1;min-height:0;overflow:hidden}.gantt-scroll-container{position:relative;width:100%;height:100%;overflow:auto}.gantt-body{display:flex;align-items:stretch;width:max-content;min-width:100%}.gantt-timeline{position:relative;flex:none}.gantt-grid{position:sticky;left:0;z-index:50;flex:none;background:var(--gantt-background);border-right:1px solid var(--gantt-border)}.gantt-grid-header{position:sticky;top:0;z-index:1;display:flex;align-items:flex-end;padding-bottom:6px;overflow:hidden;background:var(--gantt-background);border-bottom:1px solid var(--gantt-border)}.gantt-grid-header-cell{padding:0 10px;font-size:11px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--gantt-muted-foreground);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gantt-grid-body{position:relative}.gantt-grid-row{position:absolute;top:0;left:0;display:flex;width:100%;align-items:center;overflow:hidden;border-bottom:1px solid var(--gantt-border-subtle)}.gantt-grid-row:hover{background:var(--gantt-muted)}.gantt-grid-row.summary{font-weight:600}.gantt-grid-row.selected{background:var(--gantt-muted);box-shadow:inset 2px 0 0 var(--gantt-accent)}.gantt-grid-row.draggable{cursor:grab}.gantt-grid.row-dragging,.gantt-grid.row-dragging .gantt-grid-row{cursor:grabbing}.gantt-grid-row.dragging{opacity:.45}.gantt-grid-row.drop-into{background:color-mix(in srgb,var(--gantt-accent) 14%,transparent);box-shadow:inset 0 0 0 1px var(--gantt-accent)}.gantt-grid-row.drop-into.invalid,.gantt-grid.row-dragging .gantt-grid-row.drop-into.invalid{background:color-mix(in srgb,var(--gantt-today-marker) 14%,transparent);box-shadow:inset 0 0 0 1px var(--gantt-today-marker);cursor:no-drop}.gantt-grid-drop-line{position:absolute;left:0;right:0;height:2px;margin-top:-1px;background:var(--gantt-accent);pointer-events:none}.gantt-grid-drop-line:before{content:"";position:absolute;top:-3px;left:0;width:8px;height:8px;border-radius:50%;background:inherit}.gantt-grid-drop-line.invalid{background:var(--gantt-today-marker)}.gantt-grid-cell{display:flex;align-items:center;min-width:0;padding:0 10px;font-size:12px;color:var(--gantt-foreground)}.gantt-grid-cell+.gantt-grid-cell{color:var(--gantt-muted-foreground)}.gantt-grid-cell-text{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gantt-grid-indent{flex:none}.gantt-grid-expander{flex:none;display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;margin-right:4px;padding:0;color:var(--gantt-muted-foreground);background:transparent;border:none;border-radius:3px;cursor:pointer}.gantt-grid-expander:hover{color:var(--gantt-foreground);background:var(--gantt-border)}.gantt-grid-expander:focus-visible{outline:2px solid var(--gantt-accent);outline-offset:-2px}.gantt-grid-expander svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;transition:transform var(--gantt-transition-fast)}.gantt-grid-expander.open svg{transform:rotate(90deg)}.gantt-grid-expander-spacer{flex:none;width:20px}.gantt-grid-splitter{position:absolute;top:0;bottom:0;z-index:60;width:5px;cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none}.gantt-grid-splitter:hover,.gantt-grid-splitter:focus-visible{background:var(--gantt-accent);opacity:.5;outline:none}.gantt-drag-guides{position:absolute;top:0;bottom:0;left:0;z-index:40;pointer-events:none}.gantt-drag-guide{position:absolute;top:0;bottom:0;width:1px;background:var(--gantt-accent);opacity:.9}.gantt-drag-guide-label{position:absolute;top:6px;left:0;transform:translate(-50%);padding:3px 7px;background:var(--gantt-accent);color:#fff;border-radius:4px;font-family:inherit;font-size:11px;font-weight:500;white-space:nowrap}.gantt-scroll-container{scrollbar-width:thin;scrollbar-color:var(--gantt-border) transparent}.gantt-scroll-container::-webkit-scrollbar{width:10px;height:10px}.gantt-scroll-container::-webkit-scrollbar-track{background:transparent}.gantt-scroll-container::-webkit-scrollbar-thumb{background:var(--gantt-border);border-radius:5px;border:2px solid var(--gantt-background)}.gantt-scroll-container::-webkit-scrollbar-thumb:hover{background:var(--gantt-muted-foreground)}.gantt-scroll-container::-webkit-scrollbar-corner{background:transparent}.gantt-header-wrapper{position:sticky;top:0;z-index:30}.gantt-header{position:relative;background:var(--gantt-background);border-bottom:1px solid var(--gantt-border)}.gantt-header-content{display:flex;flex-direction:column}.gantt-top-header{position:relative;display:flex;height:44px;border-bottom:1px solid var(--gantt-border-subtle)}.gantt-top-groups{display:flex}.gantt-top-group{--top-group-inset: 16px;display:flex;align-items:center;padding:0 var(--top-group-inset);font-size:13px;font-weight:600;letter-spacing:-.01em;background:var(--gantt-background);color:var(--gantt-foreground)}.gantt-top-group-label{position:sticky;left:var(--top-group-inset);margin:0;padding:0;white-space:nowrap}.gantt-bottom-row{display:flex;height:28px;background:var(--gantt-muted)}.gantt-bottom-cell{display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:500;color:var(--gantt-muted-foreground);letter-spacing:.01em}.gantt-content{position:relative;background:var(--gantt-background)}.gantt-non-working-layer{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:0}.gantt-non-working-range{position:absolute;top:0;bottom:0;background:var(--gantt-non-working-bg)}.gantt-rows{position:absolute;top:0;left:0;width:100%;height:100%;z-index:0;pointer-events:none}.gantt-task-row{position:absolute;top:0;left:0;display:flex;width:100%;align-items:center;border-bottom:1px solid var(--gantt-border-subtle);pointer-events:none}.gantt-range-band-layer{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:0}.gantt-range-band{position:absolute;top:0;bottom:0;background:var(--gantt-band-color, var(--gantt-band-bg))}.gantt-range-band-label{position:absolute;top:2px;left:4px;font-size:10px;font-weight:600;color:var(--gantt-muted-foreground);white-space:nowrap}.gantt-marker{position:absolute;top:0;bottom:0;width:2px;margin-left:-1px;background:var(--gantt-marker-color, var(--gantt-marker));pointer-events:none;z-index:2}.gantt-marker[data-warning=true]{--gantt-marker-color: var(--gantt-marker-warning)}.gantt-marker-label{position:absolute;top:2px;left:3px;padding:1px 5px;font-size:10px;font-weight:600;line-height:1.4;color:var(--gantt-marker-label);background:var(--gantt-marker-color, var(--gantt-marker));border-radius:3px;white-space:nowrap}.gantt-today-marker{position:absolute;top:0;bottom:0;width:2px;margin-left:-1px;background:var(--gantt-today-marker);opacity:.7;pointer-events:none;z-index:2}.gantt-dependency-arrows{position:absolute;top:0;left:0;width:100%;pointer-events:none;z-index:0}.gantt-dependency-arrows.linking{z-index:150}.gantt-dependency-arrow{stroke:var(--gantt-arrow);stroke-width:1.5;fill:none}.gantt-dependency-arrow.selected{stroke:var(--gantt-accent);stroke-width:2.5}.gantt-dependency-arrow-head{fill:var(--gantt-arrow);stroke:none}.gantt-dependency-hit{stroke:transparent;stroke-width:12;fill:none;cursor:pointer;pointer-events:stroke}.gantt-dependency-hit:hover+.gantt-dependency-arrow{stroke:var(--gantt-accent)}.gantt-dependency-delete{cursor:pointer;pointer-events:auto}.gantt-dependency-delete circle{fill:var(--gantt-accent)}.gantt-dependency-delete path{stroke:#fff;stroke-width:1.6;stroke-linecap:round}.gantt-link-handle{position:absolute;top:50%;width:10px;height:10px;background:var(--gantt-background);border:2px solid var(--gantt-accent);border-radius:50%;transform:translateY(-50%);opacity:0;cursor:crosshair;touch-action:none;pointer-events:none;transition:opacity var(--gantt-transition-fast)}.gantt-link-handle.start{left:-14px}.gantt-link-handle.end{right:-14px}.gantt-milestone .gantt-link-handle.start{left:-9px}.gantt-milestone .gantt-link-handle.end{left:15px;right:auto}.gantt-task-bar:hover .gantt-link-handle,.gantt-milestone:hover .gantt-link-handle,.gantt-task-bar.selected .gantt-link-handle,.gantt-milestone.selected .gantt-link-handle{opacity:1;pointer-events:auto}.gantt-task-bar.link-target,.gantt-milestone.link-target .gantt-milestone-diamond{outline:2px solid var(--gantt-accent);outline-offset:2px}.gantt-task-bar.link-target.invalid,.gantt-milestone.link-target.invalid .gantt-milestone-diamond{outline-color:var(--gantt-today-marker)}.gantt-link-preview-line{stroke:var(--gantt-accent);stroke-width:2;stroke-dasharray:4 3;fill:none}.gantt-link-preview-line.invalid{stroke:var(--gantt-today-marker)}.gantt-link-preview-origin{fill:var(--gantt-accent)}.gantt-link-preview-reason{fill:var(--gantt-today-marker);font-family:inherit;font-size:11px;font-weight:500;paint-order:stroke;stroke:var(--gantt-background);stroke-width:3px;stroke-linejoin:round}.gantt-content.drawable{cursor:crosshair}.gantt-draw-ghost{position:absolute;top:0;left:0;height:19px;margin-top:9px;background:var(--gantt-accent);opacity:.35;border:1px dashed var(--gantt-accent);border-radius:6px;pointer-events:none;z-index:5}.gantt-task-bar{position:relative;touch-action:pan-x pan-y;z-index:10;display:flex;align-items:center;background:var(--gantt-bar-color, var(--gantt-bar-bg));border-radius:6px;-webkit-user-select:none;user-select:none;cursor:grab;box-shadow:var(--gantt-bar-shadow);transition:background var(--gantt-transition-fast),box-shadow var(--gantt-transition-normal)}.gantt-task-bar:before,.gantt-task-bar:after{content:"";position:absolute;top:50%;width:3px;height:12px;background:var(--gantt-muted-foreground);border-radius:2px;opacity:0;transform:translateY(-50%);transition:opacity var(--gantt-transition-fast)}.gantt-task-bar:before{left:4px}.gantt-task-bar:after{right:4px}.gantt-task-bar:hover{background:var(--gantt-bar-color-hover, var(--gantt-bar-bg-hover));box-shadow:var(--gantt-bar-shadow-hover)}.gantt-task-bar:hover:before,.gantt-task-bar:hover:after{opacity:.5}.gantt-task-bar:active,.gantt-task-bar.dragging{cursor:grabbing;box-shadow:var(--gantt-bar-shadow-drag);z-index:100}.gantt-task-bar.dragging:before,.gantt-task-bar.dragging:after{opacity:.7}.gantt-task-bar.summary{background:var(--gantt-bar-color, var(--gantt-milestone-bg));border-radius:3px}.gantt-task-bar.summary:hover{background:var(--gantt-bar-color-hover, var(--gantt-milestone-bg-hover))}.gantt-task-bar.summary .gantt-task-name{color:var(--gantt-background)}.gantt-task-bar.summary .gantt-task-name.outside{color:var(--gantt-foreground)}.gantt-task-bar.summary .gantt-progress-fill{background:var(--gantt-progress-color, var(--gantt-foreground));opacity:.35;border-radius:3px 0 0 3px}.gantt-task-bar.summary:before,.gantt-task-bar.summary:after,.gantt-task-bar.summary:hover:before,.gantt-task-bar.summary:hover:after{opacity:0}.gantt-baseline{position:absolute;bottom:3px;height:4px;background:var(--gantt-baseline-bg);border-radius:2px;opacity:.65;pointer-events:none}.gantt-baseline.milestone{width:8px;height:8px;bottom:1px;margin-left:-4px;border-radius:1px;transform:rotate(45deg)}.gantt-task-bar.critical{background:var(--gantt-critical-bg)}.gantt-task-bar.critical:hover{background:var(--gantt-critical-bg-hover)}.gantt-task-bar.critical .gantt-task-name{color:var(--gantt-critical-text)}.gantt-task-bar.critical .gantt-task-name.outside{color:var(--gantt-foreground)}.gantt-task-bar.critical .gantt-progress-fill{background:var(--gantt-critical);opacity:.45}.gantt-milestone.critical .gantt-milestone-diamond{background:var(--gantt-critical)}.gantt-dependency-arrow.critical{stroke:var(--gantt-critical);stroke-width:2}.gantt-dependency-arrow-head.critical{fill:var(--gantt-critical)}.gantt-task-bar.selected,.gantt-milestone.selected .gantt-milestone-diamond{outline:2px solid var(--gantt-accent);outline-offset:2px}.gantt-task-bar.reverting,.gantt-milestone.reverting{transition:transform var(--gantt-transition-normal),width var(--gantt-transition-normal),background var(--gantt-transition-fast),box-shadow var(--gantt-transition-normal)}.gantt-task-bar.reverting .gantt-progress-fill,.gantt-task-bar.reverting .gantt-progress-handle{transition:width var(--gantt-transition-normal),left var(--gantt-transition-normal)}.gantt-task-bar.compact:before,.gantt-task-bar.compact:after,.gantt-task-bar.compact:hover:before,.gantt-task-bar.compact:hover:after,.gantt-task-bar.compact.dragging:before,.gantt-task-bar.compact.dragging:after,.gantt-task-bar.no-resize:before,.gantt-task-bar.no-resize:after,.gantt-task-bar.no-resize:hover:before,.gantt-task-bar.no-resize:hover:after,.gantt-task-bar.no-resize.dragging:before,.gantt-task-bar.no-resize.dragging:after{opacity:0}.gantt-progress-fill{position:absolute;top:0;left:0;bottom:0;background:var(--gantt-progress-color, var(--gantt-progress-bg));border-radius:6px 0 0 6px;pointer-events:none}.gantt-progress-handle{position:absolute;top:50%;width:10px;height:10px;margin-left:-5px;background:var(--gantt-background);border:2px solid var(--gantt-progress-handle);border-radius:50%;transform:translateY(-50%);opacity:0;cursor:ew-resize;transition:opacity var(--gantt-transition-fast)}.gantt-task-bar:hover .gantt-progress-handle,.gantt-progress-handle.dragging{opacity:1}@media(hover:none){.gantt-progress-handle{opacity:1}.gantt-progress-handle:before{content:"";position:absolute;top:-17px;right:-17px;bottom:-17px;left:-17px}}.gantt-task-name{position:relative;flex:1;padding:0 14px;font-family:inherit;font-size:12px;font-weight:500;color:var(--gantt-bar-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none}.gantt-task-name.outside{position:absolute;left:100%;flex:none;padding:0 0 0 8px;color:var(--gantt-foreground);overflow:visible}.gantt-milestone{position:relative;touch-action:pan-x pan-y;z-index:10;display:flex;align-items:center;gap:10px;-webkit-user-select:none;user-select:none;cursor:grab}.gantt-milestone-diamond{flex-shrink:0;width:16px;height:16px;background:var(--gantt-bar-color, var(--gantt-milestone-bg));border-radius:3px;transform:rotate(45deg);box-shadow:var(--gantt-bar-shadow);transition:background var(--gantt-transition-fast),box-shadow var(--gantt-transition-normal)}.gantt-milestone:hover .gantt-milestone-diamond{background:var(--gantt-bar-color-hover, var(--gantt-milestone-bg-hover));box-shadow:var(--gantt-bar-shadow-hover)}.gantt-milestone:active,.gantt-milestone.dragging{cursor:grabbing;z-index:100}.gantt-milestone.dragging .gantt-milestone-diamond{box-shadow:var(--gantt-bar-shadow-drag)}.gantt-milestone-name{font-family:inherit;font-size:12px;font-weight:500;color:var(--gantt-foreground);white-space:nowrap;pointer-events:none}.gantt-bar-tooltip{position:absolute;top:calc(100% + 8px);left:50%;transform:translate(-50%);z-index:200;padding:8px 12px;background:var(--gantt-foreground);color:var(--gantt-background);border-radius:6px;font-family:inherit;font-size:11px;font-weight:500;white-space:nowrap;box-shadow:0 4px 16px #00000026;pointer-events:none;animation:tooltipFadeIn var(--gantt-duration-fast) ease-out}@keyframes tooltipFadeIn{0%{opacity:0;transform:translate(-50%) translateY(-4px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.gantt-bar-tooltip-detail{display:flex;flex-direction:column;gap:2px;text-align:left}.gantt-tooltip-name{font-weight:600}.gantt-tooltip-meta{opacity:.75}.gantt-bar-tooltip:after{content:"";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border:5px solid transparent;border-bottom-color:var(--gantt-foreground)}@media(max-width:768px){.gantt-toolbar{padding:8px 12px}.gantt-scale-button{padding:5px 10px;font-size:11px}.gantt-top-group{--top-group-inset: 12px;font-size:12px}.gantt-bottom-cell{font-size:10px}.gantt-task-name{font-size:11px;padding:0 10px}}.gantt-grid-row.group,.gantt-task-row.group{background:var(--gantt-muted);font-weight:600}.gantt-grid-row.group .gantt-grid-cell{gap:6px}.gantt-group-label{position:sticky;left:0;display:flex;align-items:center;gap:6px;height:100%;padding:0 10px;pointer-events:auto;font-weight:600;white-space:nowrap}.gantt-grid-group-count{flex:none;padding:0 6px;border-radius:999px;background:var(--gantt-border);color:var(--gantt-muted-foreground);font-size:10px;font-weight:600;line-height:16px}.gantt-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;border:0;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}.gantt-container [data-gantt-cell]:focus-visible{outline:2px solid var(--gantt-accent);outline-offset:1px}@media(prefers-reduced-motion:reduce){.gantt-container *,.gantt-container *:before,.gantt-container *:after{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important}}
1
+ .gantt-container{color-scheme:light;--gantt-detail-width: 320px;--gantt-font-sans: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, "Segoe UI", "Geist", system-ui, sans-serif;--gantt-background: #fafafa;--gantt-foreground: #18181b;--gantt-muted: #f4f4f5;--gantt-muted-foreground: #71717a;--gantt-border: #e4e4e7;--gantt-border-subtle: rgba(0, 0, 0, .04);--gantt-bar-bg: #c7c7cd;--gantt-bar-bg-hover: #b4b4bc;--gantt-bar-text: #18181b;--gantt-bar-shadow: none;--gantt-bar-shadow-hover: 0 1px 2px rgba(0, 0, 0, .08);--gantt-bar-shadow-drag: 0 4px 12px rgba(0, 0, 0, .16);--gantt-shadow-overlay: 0 4px 16px rgba(0, 0, 0, .15);--gantt-arrow: #a1a1aa;--gantt-accent: #3b82f6;--gantt-today-marker: #f43f5e;--gantt-summary-bg: #dcdce0;--gantt-summary-bg-hover: #cfcfd4;--gantt-progress-bg: #8e8e97;--gantt-progress-handle: #52525b;--gantt-non-working-bg: rgba(0, 0, 0, .035);--gantt-duration-fast: .15s;--gantt-transition-fast: .15s ease;--gantt-transition-normal: .2s ease}.gantt-container[data-theme=dark]{color-scheme:dark;--gantt-background: #09090b;--gantt-foreground: #fafafa;--gantt-muted: #18181b;--gantt-muted-foreground: #a1a1aa;--gantt-border: #27272a;--gantt-border-subtle: rgba(255, 255, 255, .04);--gantt-bar-bg: #3a3a41;--gantt-bar-bg-hover: #47474f;--gantt-bar-text: #fafafa;--gantt-bar-shadow: none;--gantt-bar-shadow-hover: 0 1px 2px rgba(0, 0, 0, .4);--gantt-bar-shadow-drag: 0 4px 12px rgba(0, 0, 0, .5);--gantt-shadow-overlay: 0 8px 24px rgba(0, 0, 0, .55), 0 0 0 1px rgba(255, 255, 255, .08);--gantt-arrow: #71717a;--gantt-today-marker: #fb7185;--gantt-summary-bg: #2a2a2f;--gantt-summary-bg-hover: #35353c;--gantt-progress-bg: #6c6c76;--gantt-progress-handle: #a1a1aa;--gantt-non-working-bg: rgba(255, 255, 255, .03)}.gantt-container,.gantt-container *,.gantt-container *:before,.gantt-container *:after{box-sizing:border-box}.gantt-container{display:flex;flex-direction:column;overflow:hidden;isolation:isolate;background:var(--gantt-background);font-family:var(--gantt-font-sans);font-size:13px;line-height:1.5;color:var(--gantt-foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.gantt-container:focus{outline:none}.gantt-main{position:relative;flex:1;min-height:0;overflow:hidden;display:flex;flex-direction:column}.gantt-scroll-container{position:relative;width:100%;flex:1;min-height:0;overflow:auto}.gantt-body{display:flex;align-items:stretch;width:max-content;min-width:100%;min-height:100%}.gantt-timeline{position:relative;flex:1 0 auto;display:flex;flex-direction:column;isolation:isolate}.gantt-grid{position:sticky;left:0;z-index:50;flex:none;display:flex;flex-direction:column;background:var(--gantt-background);border-right:1px solid var(--gantt-border)}.gantt-grid-header{position:sticky;top:0;flex:none;z-index:1;display:flex;align-items:flex-end;padding-bottom:6px;overflow:hidden;background:var(--gantt-background);border-bottom:1px solid var(--gantt-border)}.gantt-grid-header-cell{flex:1;min-width:0;padding:0 10px;font-size:11px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--gantt-muted-foreground);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gantt-grid-body{position:relative}.gantt-grid-row{position:absolute;top:0;left:0;display:flex;width:100%;align-items:center;overflow:hidden;border-bottom:1px solid var(--gantt-border-subtle)}.gantt-grid-row:hover{background:var(--gantt-muted)}.gantt-grid-row.summary{font-weight:600}.gantt-grid-row.selected{background:var(--gantt-muted);box-shadow:inset 2px 0 0 var(--gantt-accent)}.gantt-grid-row.dragging{opacity:.45}.gantt-grid-cell{flex:1;display:flex;align-items:center;min-width:0;padding:0 10px;font-size:12px;color:var(--gantt-foreground)}.gantt-grid-cell-text{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gantt-grid-indent{flex:none}.gantt-grid-no{flex:none;min-width:2.25rem;margin-right:4px;font-size:11px;font-weight:400;font-variant-numeric:tabular-nums;color:var(--gantt-muted-foreground);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gantt-grid-expander{flex:none;display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;margin-right:4px;padding:0;color:var(--gantt-muted-foreground);background:transparent;border:none;border-radius:3px;cursor:pointer}.gantt-grid-expander:hover{color:var(--gantt-foreground);background:var(--gantt-border)}.gantt-grid-expander:focus-visible{outline:2px solid var(--gantt-accent);outline-offset:-2px}.gantt-grid-expander svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;transition:transform var(--gantt-transition-fast)}.gantt-grid-expander.open svg{transform:rotate(90deg)}.gantt-grid-expander-spacer{flex:none;width:20px}.gantt-grid-grip{flex:none;display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;margin-right:4px;padding:0;color:var(--gantt-muted-foreground);background:transparent;border:none;border-radius:3px;opacity:0;cursor:grab;transition:opacity var(--gantt-transition-fast)}.gantt-grid-row:hover .gantt-grid-grip,.gantt-grid-row:focus-within .gantt-grid-grip{opacity:1}.gantt-grid-grip:active{cursor:grabbing}.gantt-grid-grip svg{width:12px;height:12px;fill:currentColor}.gantt-grid-grip-spacer{flex:none;width:20px}.gantt-grid-drop{position:absolute;left:0;right:0;height:2px;margin-top:-1px;color:var(--gantt-accent);background:currentColor;pointer-events:none}.gantt-grid-drop.child{height:auto;margin-top:0;background:none;border-radius:3px;box-shadow:inset 0 0 0 2px currentColor}.gantt-grid-drop.blocked{color:var(--gantt-today-marker)}.gantt-grid-splitter{position:absolute;top:0;bottom:0;z-index:60;width:5px;cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none}.gantt-grid-splitter:hover,.gantt-grid-splitter:focus-visible{background:var(--gantt-accent);opacity:.5;outline:none}.gantt-grid-footer{flex:none;display:flex;align-items:center;height:34px;padding:0 6px;background:var(--gantt-background);border-top:1px solid var(--gantt-border);border-right:1px solid var(--gantt-border)}.gantt-grid-add{display:inline-flex;align-items:center;gap:6px;width:100%;min-width:0;padding:5px 8px;font:inherit;font-size:12px;color:var(--gantt-muted-foreground);text-align:left;white-space:nowrap;overflow:hidden;background:transparent;border:none;border-radius:4px;cursor:pointer}.gantt-grid-add:hover{color:var(--gantt-foreground);background:var(--gantt-muted)}.gantt-grid-add:focus-visible{outline:2px solid var(--gantt-accent);outline-offset:-2px}.gantt-grid-add svg{flex:none;width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round}.gantt-drag-guides{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none}.gantt-drag-cell{position:absolute;top:44px;height:28px;display:flex;align-items:center;justify-content:center;background:var(--gantt-muted)}.gantt-drag-cell>span{flex:none;padding:0 6px;background:var(--gantt-muted);color:var(--gantt-foreground);font-family:inherit;font-size:11px;font-weight:500;line-height:28px;letter-spacing:.01em;white-space:nowrap}.gantt-drag-footprint{position:absolute;top:49px;height:18px;border-radius:6px;background:color-mix(in srgb,var(--gantt-foreground) 6%,transparent)}.gantt-holiday-labels{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none}.gantt-holiday-band{position:absolute;top:0;bottom:0;pointer-events:auto}.gantt-holiday-cell{position:absolute;top:44px;height:28px;display:flex;align-items:center;justify-content:center;overflow:hidden;background:var(--gantt-muted);opacity:0;transition:opacity 90ms ease-out}.gantt-holiday-cell.shown,.gantt-holiday-band:hover .gantt-holiday-cell{opacity:1}@media(prefers-reduced-motion:reduce){.gantt-holiday-cell{transition:none}}.gantt-holiday-cell>span{padding:0 6px;color:var(--gantt-foreground);font-family:inherit;font-size:11px;font-weight:500;line-height:28px;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gantt-scroll-container{scrollbar-width:thin;scrollbar-color:var(--gantt-border) transparent}.gantt-scroll-container::-webkit-scrollbar{width:10px;height:10px}.gantt-scroll-container::-webkit-scrollbar-track{background:transparent}.gantt-scroll-container::-webkit-scrollbar-thumb{background:var(--gantt-border);border-radius:5px;border:2px solid var(--gantt-background)}.gantt-scroll-container::-webkit-scrollbar-thumb:hover{background:var(--gantt-muted-foreground)}.gantt-scroll-container::-webkit-scrollbar-corner{background:transparent}.gantt-header-wrapper{position:sticky;top:0;flex:none;z-index:30;min-width:100%}.gantt-header{position:relative;min-width:100%;background:var(--gantt-background);border-bottom:1px solid var(--gantt-border)}.gantt-header-content{display:flex;flex-direction:column}.gantt-top-header{position:relative;display:flex;height:44px;border-bottom:1px solid var(--gantt-border-subtle)}.gantt-top-groups{display:flex}.gantt-top-group{--top-group-inset: 16px;display:flex;align-items:center;padding:0 var(--top-group-inset);font-size:13px;font-weight:600;letter-spacing:-.01em;background:var(--gantt-background);color:var(--gantt-foreground)}.gantt-top-group-label{position:sticky;left:calc(var(--gantt-pane-inset, 0px) + var(--top-group-inset));margin:0;padding:0;white-space:nowrap;min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis}.gantt-bottom-row{display:flex;height:28px;background:var(--gantt-muted)}.gantt-bottom-cell{display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:500;color:var(--gantt-muted-foreground);letter-spacing:.01em}.gantt-content{position:relative;min-width:100%;background:var(--gantt-background)}.gantt-non-working-layer{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none}.gantt-non-working-range{position:absolute;top:0;bottom:0;background:var(--gantt-non-working-bg)}.gantt-rows{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none}.gantt-task-row{position:absolute;top:0;left:0;display:flex;width:100%;align-items:center;border-bottom:1px solid var(--gantt-border-subtle);pointer-events:none}.gantt-content,.gantt-grid-body{flex:1 0 auto;background-image:repeating-linear-gradient(to bottom,transparent 0,transparent calc(var(--gantt-row-height) - 1px),var(--gantt-border-subtle) calc(var(--gantt-row-height) - 1px),var(--gantt-border-subtle) var(--gantt-row-height))}.gantt-today-marker{position:absolute;top:0;bottom:0;width:1px;background:var(--gantt-today-marker);opacity:.6;pointer-events:none}.gantt-today-dot{position:absolute;bottom:0;width:6px;height:6px;border-radius:50%;background:var(--gantt-today-marker);transform:translate(-50%,50%);pointer-events:none}.gantt-dependency-arrows{position:absolute;top:0;left:0;width:100%;pointer-events:none;z-index:0}.gantt-dependency-arrows.linking{z-index:45}.gantt-dependency-arrows.linking .gantt-dependency-hit,.gantt-dependency-arrows.linking .gantt-dependency-delete{pointer-events:none}.gantt-dependency-arrow{stroke:var(--gantt-arrow);stroke-width:1.5;fill:none;opacity:.45}.gantt-dependency-arrow.selected,.gantt-dependency-arrow.related,.gantt-dependency-hit:hover+.gantt-dependency-arrow{opacity:1}.gantt-dependency-arrow.selected{stroke:var(--gantt-accent);stroke-width:2.5}.gantt-dependency-arrow-head{fill:var(--gantt-arrow);stroke:none}.gantt-dependency-hit{stroke:transparent;stroke-width:12;fill:none;cursor:pointer;pointer-events:stroke}.gantt-dependency-hit:hover+.gantt-dependency-arrow{stroke:var(--gantt-accent)}.gantt-dependency-delete{cursor:pointer;pointer-events:auto}.gantt-dependency-delete circle{fill:var(--gantt-accent)}.gantt-dependency-delete path{stroke:#fff;stroke-width:1.6;stroke-linecap:round}.gantt-link-handle{position:absolute;top:50%;width:12px;height:12px;background:var(--gantt-background);border:2px solid var(--gantt-accent);border-radius:50%;transform:translateY(-50%);opacity:0;cursor:crosshair;touch-action:none;pointer-events:none;transition:opacity var(--gantt-transition-fast)}.gantt-link-handle.start{left:-18px}.gantt-link-handle.end{right:-18px}.gantt-link-handle:before{content:"";position:absolute}.gantt-link-handle.start:before{top:-8px;right:-6px;bottom:-8px;left:-8px}.gantt-link-handle.end:before{top:-8px;right:-8px;bottom:-8px;left:-6px}.gantt-task-bar:hover .gantt-link-handle,.gantt-task-bar.selected .gantt-link-handle{opacity:1;pointer-events:auto}.gantt-task-bar.link-source.link-at-start .gantt-link-handle.start,.gantt-task-bar.link-source.link-at-end .gantt-link-handle.end{opacity:1}@media(hover:none){.gantt-link-handle{opacity:.55;pointer-events:auto}}.gantt-task-bar.link-valid,.gantt-task-bar.link-invalid{outline:2px solid var(--gantt-accent);outline-offset:2px}.gantt-task-bar.link-valid{background:var(--gantt-bar-color-hover, var(--gantt-bar-bg-hover));box-shadow:0 0 0 4px color-mix(in srgb,var(--gantt-accent) 25%,transparent)}.gantt-task-bar.link-invalid{outline-color:var(--gantt-today-marker);box-shadow:none}.gantt-task-bar.link-valid .gantt-link-handle.start,.gantt-task-bar.link-valid .gantt-link-handle.end{opacity:0}.gantt-task-bar.link-valid.link-at-start .gantt-link-handle.start,.gantt-task-bar.link-valid.link-at-end .gantt-link-handle.end{opacity:1;background:var(--gantt-accent)}.gantt-link-preview-line{stroke:var(--gantt-accent);stroke-width:2;stroke-dasharray:4 3;fill:none}.gantt-link-preview-line.armed{stroke-dasharray:none;stroke-width:2.5}.gantt-link-preview-line.invalid{stroke:var(--gantt-today-marker)}.gantt-link-preview-origin{fill:var(--gantt-accent)}.gantt-link-preview-type{fill:var(--gantt-accent);font-family:inherit;font-size:11px;font-weight:600;letter-spacing:.04em;paint-order:stroke;stroke:var(--gantt-background);stroke-width:3px;stroke-linejoin:round}.gantt-link-preview-reason{fill:var(--gantt-today-marker);font-family:inherit;font-size:11px;font-weight:500;paint-order:stroke;stroke:var(--gantt-background);stroke-width:3px;stroke-linejoin:round}.gantt-content.drawable{cursor:crosshair}.gantt-draw-ghost{position:absolute;top:0;left:0;background:var(--gantt-accent);opacity:.35;border:1px dashed var(--gantt-accent);border-radius:6px;pointer-events:none;z-index:5}.gantt-bar-wrap:has(>.gantt-task-bar.has-tooltip){z-index:1}.gantt-bar-wrap:has(>.gantt-task-bar.dragging){z-index:2}.gantt-task-bar{position:relative;touch-action:pan-x pan-y;display:flex;align-items:center;background:var(--gantt-bar-color, var(--gantt-bar-bg));border-radius:6px;-webkit-user-select:none;user-select:none;cursor:grab;box-shadow:var(--gantt-bar-shadow);transition:background var(--gantt-transition-fast),box-shadow var(--gantt-transition-normal)}.gantt-task-bar:before,.gantt-task-bar:after{content:"";position:absolute;top:50%;width:3px;height:12px;background:var(--gantt-muted-foreground);border-radius:2px;opacity:0;transform:translateY(-50%);transition:opacity var(--gantt-transition-fast)}.gantt-task-bar:before{left:4px}.gantt-task-bar:after{right:4px}.gantt-task-bar:hover{background:var(--gantt-bar-color-hover, var(--gantt-bar-bg-hover));box-shadow:var(--gantt-bar-shadow-hover)}.gantt-task-bar:hover:before,.gantt-task-bar:hover:after{opacity:.5}.gantt-task-bar:active,.gantt-task-bar.dragging{cursor:grabbing;box-shadow:var(--gantt-bar-shadow-drag)}.gantt-task-bar.summary{background:var(--gantt-bar-color, var(--gantt-summary-bg));border-radius:3px}.gantt-task-bar.summary:hover{background:var(--gantt-bar-color-hover, var(--gantt-summary-bg-hover))}.gantt-task-bar.summary .gantt-progress-fill{background:var(--gantt-progress-color, var(--gantt-foreground));opacity:.25}.gantt-task-bar.selected{outline:2px solid var(--gantt-accent);outline-offset:2px}.gantt-task-bar.compact:before,.gantt-task-bar.compact:after,.gantt-task-bar.compact:hover:before,.gantt-task-bar.compact:hover:after,.gantt-task-bar.compact.dragging:before,.gantt-task-bar.compact.dragging:after,.gantt-task-bar.no-resize:before,.gantt-task-bar.no-resize:after,.gantt-task-bar.no-resize:hover:before,.gantt-task-bar.no-resize:hover:after,.gantt-task-bar.no-resize.dragging:before,.gantt-task-bar.no-resize.dragging:after{opacity:0}.gantt-progress-fill{position:absolute;top:0;left:0;bottom:0;background:var(--gantt-progress-color, var(--gantt-progress-bg));border-radius:inherit;pointer-events:none}.gantt-progress-handle{position:absolute;top:50%;width:10px;height:10px;margin-left:-5px;background:var(--gantt-background);border:2px solid var(--gantt-progress-handle);border-radius:50%;transform:translateY(-50%);opacity:0;cursor:ew-resize;transition:opacity var(--gantt-transition-fast)}.gantt-task-bar:hover .gantt-progress-handle,.gantt-progress-handle.dragging{opacity:1}@media(hover:none){.gantt-progress-handle{opacity:1}.gantt-progress-handle:before{content:"";position:absolute;top:-17px;right:-17px;bottom:-17px;left:-17px}}.gantt-task-name{position:relative;flex:1;padding:0 14px;font-family:inherit;font-size:12px;font-weight:500;color:var(--gantt-bar-text-color, var(--gantt-bar-text));white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none}.gantt-task-name.outside{position:absolute;left:100%;flex:none;padding:0 0 0 8px;color:var(--gantt-muted-foreground);max-width:160px;overflow:hidden;text-overflow:ellipsis}.gantt-task-bar:hover .gantt-task-name.outside,.gantt-task-bar.selected .gantt-task-name.outside,.gantt-task-bar.dragging .gantt-task-name.outside{color:var(--gantt-foreground)}.gantt-bar-tooltip{position:absolute;top:calc(100% + 8px);left:50%;transform:translate(-50%);padding:8px 12px;background:var(--gantt-foreground);color:var(--gantt-background);border-radius:6px;font-family:inherit;font-size:11px;font-weight:500;white-space:nowrap;box-shadow:var(--gantt-shadow-overlay);pointer-events:none;animation:tooltipFadeIn var(--gantt-duration-fast) ease-out}@keyframes tooltipFadeIn{0%{opacity:0;transform:translate(-50%) translateY(-4px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.gantt-bar-tooltip-detail{display:flex;flex-direction:column;gap:2px;text-align:left}.gantt-tooltip-name{font-weight:600}.gantt-tooltip-meta{opacity:.75}.gantt-bar-tooltip:after{content:"";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border:5px solid transparent;border-bottom-color:var(--gantt-foreground)}@media(max-width:768px){.gantt-top-group{--top-group-inset: 12px;font-size:12px}.gantt-bottom-cell{font-size:10px}.gantt-task-name{font-size:11px;padding:0 10px}}.gantt-grid-lane-count{flex:none;padding:0 6px;border-radius:999px;background:var(--gantt-border);color:var(--gantt-muted-foreground);font-size:10px;font-weight:600;line-height:16px}.gantt-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;border:0;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}.gantt-container [data-gantt-cell]:focus-visible{outline:2px solid var(--gantt-accent);outline-offset:1px}@media(prefers-reduced-motion:reduce){.gantt-container *,.gantt-container *:before,.gantt-container *:after{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important}}.gantt-layout{display:flex;flex:1;min-height:0}.gantt-detail{position:relative;flex:0 0 0px;display:flex;flex-direction:column;gap:12px;padding:16px 0;overflow:hidden auto;border-left:0 solid var(--gantt-border);background:var(--gantt-background);color:var(--gantt-foreground);transition:flex-basis .2s ease,padding .2s ease,border-left-width .2s ease}.gantt-detail-open{flex-basis:var(--gantt-detail-width);padding:16px;border-left-width:1px}.gantt-detail>*{min-width:calc(var(--gantt-detail-width) - 32px)}.gantt-detail-header{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.gantt-detail-title{margin:0;font-size:14px;font-weight:600;line-height:1.4}.gantt-detail-close{flex:0 0 auto;padding:2px 6px;border:none;border-radius:4px;background:none;color:var(--gantt-muted-foreground);font-size:13px;line-height:1;cursor:pointer}.gantt-detail-close:hover{background:var(--gantt-muted);color:var(--gantt-foreground)}.gantt-detail-close:focus-visible{outline:2px solid var(--gantt-accent);outline-offset:1px}.gantt-detail-fields{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:8px 16px;margin:0;font-size:12px}.gantt-detail-fields dt{color:var(--gantt-muted-foreground)}.gantt-detail-fields dd{margin:0;overflow-wrap:anywhere}.gantt-detail-input{padding:2px 6px;border:1px solid var(--gantt-border);border-radius:4px;background:var(--gantt-background);color:var(--gantt-foreground);font:inherit;font-size:12px}.gantt-detail-input:focus-visible{outline:2px solid var(--gantt-accent);outline-offset:1px}.gantt-detail-header .gantt-detail-input{flex:1;min-width:0;font-size:14px;font-weight:600}.gantt-detail-fields .gantt-detail-input{width:100%}