/* ============================================================================
   GANTT — on-canvas timeline. A `gantt` node is a section-style box drawing a
   time axis; its bars are REAL `task`-nodes restyled with `.is-bar` (so they
   keep ports and connect to other nodes with normal connector lines).
   Kept in its own file so it never contends with style.css.
   ============================================================================ */

/* ---- the timeline box (sits behind the bars) ---- */
.card.gantt {
  position: absolute;
  /* transparent — the opaque lane fill is drawn as a backdrop rect in the
     below-cards layer (see renderEdges .gantt-backdrop) so the main canvas grid
     can't bleed through, while dependency lines still sit above that backdrop
     and are occluded by the opaque bars. */
  background: transparent;
  border: 1px solid #2b3a4a;
  border-radius: 12px;
  box-shadow: 0 6px 22px -10px #000a;
  overflow: hidden;
  padding: 0;
  cursor: default;
}
.gantt-backdrop { fill: #0f1720; }
.card.gantt.sel { border-color: #60a5fa; box-shadow: 0 0 0 1px #60a5fa inset, 0 6px 22px -10px #000a; }

.card.gantt .g-bar {
  position: absolute; top: 0; left: 0; right: 0; z-index: 3;
  display: flex; align-items: center; gap: 10px;
  height: 40px; padding: 0 10px;
  background: #15202c; border-bottom: 1px solid #24313f;
  cursor: grab; user-select: none;
}
.card.gantt.dragging .g-bar { cursor: grabbing; }
.card.gantt.pinned .g-bar { cursor: default; }   /* pinned = anchored, no move */
.card.gantt .g-title { font-weight: 600; font-size: 13px; color: #e7edf4; }
.card.gantt .g-count { font-size: 11px; color: #7c8aa0; }
.card.gantt .g-sp { flex: 1; }
.card.gantt .g-add {
  font-size: 12px; padding: 4px 9px; border-radius: 6px;
  background: #60a5fa; color: #06183a; border: 0; font-weight: 600; cursor: pointer;
}
.card.gantt .g-add:hover { filter: brightness(1.06); }

/* two-tier time axis: coarse band (month/year) over unit ticks (day/week/…) */
.card.gantt .g-head { position: absolute; left: 0; right: 0; z-index: 2; overflow: hidden; background: #101923; border-bottom: 1px solid #24313f; }
.card.gantt .g-head-top { position: absolute; top: 0; left: 0; right: 0; height: 21px; }
.card.gantt .g-head-bot { position: absolute; top: 21px; left: 0; right: 0; bottom: 0; }
.card.gantt .g-band {
  position: absolute; top: 0; height: 21px; line-height: 21px;
  font-size: 11px; font-weight: 600; color: #aebccd; white-space: nowrap; overflow: hidden;
  padding-left: 6px; border-left: 1px solid #2b3a4a; box-sizing: border-box;
}
.card.gantt .g-tick {
  position: absolute; top: 0; bottom: 0; line-height: 20px; text-align: center;
  font-size: 10px; color: #6f7f92; white-space: nowrap; overflow: hidden;
  border-left: 1px solid #1b2836; box-sizing: border-box;
}

/* full-height gridlines + today marker, behind everything */
.card.gantt .g-grid { position: absolute; left: 0; right: 0; bottom: 0; z-index: 0; pointer-events: none; }
.card.gantt .g-mline { position: absolute; top: 0; bottom: 0; width: 1px; background: #223243; }
.card.gantt .g-fline { position: absolute; top: 0; bottom: 0; width: 1px; background: #141e29; }
.card.gantt .g-today { position: absolute; top: 0; bottom: 0; width: 2px; background: #f0883e88; }
/* weekend (Sat/Sun) column shading — translucent red so bars stay readable */
.card.gantt .g-weekend { position: absolute; top: 0; bottom: 0; background: rgba(239, 68, 68, .14); }

/* scale-mode control (Day / Week / Month / Quarter) in the header */
.card.gantt .g-modes { display: inline-flex; border: 1px solid #2f4257; border-radius: 6px; overflow: hidden; }
.card.gantt .g-mode {
  padding: 3px 10px; font-size: 11px; cursor: pointer;
  background: #182430; color: #9fb0c4; border: 0; border-right: 1px solid #2f4257;
}
.card.gantt .g-mode:last-child { border-right: 0; }
.card.gantt .g-mode:hover { background: #22303f; }
.card.gantt .g-mode.on { background: #2f6fb0; color: #fff; }

.card.gantt .g-resize {
  position: absolute; right: 0; bottom: 0; width: 18px; height: 18px; z-index: 4;
  cursor: nwse-resize; background:
    linear-gradient(135deg, transparent 0 40%, #3a4c60 40% 52%, transparent 52% 66%, #3a4c60 66% 78%, transparent 78%);
}
.card.gantt .g-resize:hover { filter: brightness(1.4); }

/* ---- a task-node restyled as a bar ---- */
.card.is-bar {
  width: var(--bar-w, 80px);
  min-height: 0; height: 24px;
  padding: 0 8px;
  display: flex; align-items: center;
  border-radius: 6px;
  background: #2f6fb0; border: 1px solid #4b8bd0; color: #eaf2fb;
  box-shadow: 0 2px 6px -2px #0008;
  overflow: visible;   /* keep ports reachable at the edges */
}
/* Label strategy (Frappe/DHTMLX/Jira): INSIDE the bar when it fits, spilled to
   the RIGHT only for short bars. Class set per-bar in cardEl from a text measure. */
.card.is-bar.lbl-in .ttl {
  flex: 1 1 auto; min-width: 0;
  font-size: 11.5px; font-weight: 600; line-height: 1; color: var(--bar-fg, #fff);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-shadow: 0 1px 1px #0004; pointer-events: none;
}
/* Spilled label is rendered on the top layer (.bar-out-label in #labels-top),
   above the dependency lines — so hide the in-card copy. */
.card.is-bar.lbl-out .ttl { display: none; }
.bar-out-label {
  position: absolute; transform: translateY(-50%);
  font: 600 12px system-ui, -apple-system, sans-serif;
  white-space: nowrap; color: #eaf2fb; pointer-events: none;
  /* strong halo so it also reads over gridlines */
  text-shadow: 0 0 3px #0d0f12, 0 0 3px #0d0f12, 0 1px 4px #000e;
}
.bar-out-label.done { text-decoration: line-through; opacity: .8; }
.bar-out-label.dim { opacity: .32; }
/* the bar's own chrome we don't want in the compact form */
.card.is-bar .sub,
.card.is-bar .meta,
.card.is-bar .task-tick { display: none !important; }

/* edge resize handles — drag ends to change start/end dates */
.card.is-bar .bar-rz { position: absolute; top: 0; bottom: 0; width: 8px; cursor: ew-resize; z-index: 2; opacity: 0; }
.card.is-bar .bar-rz-l { left: -1px; border-radius: 6px 0 0 6px; }
.card.is-bar .bar-rz-r { right: -1px; border-radius: 0 6px 6px 0; }
.card.is-bar:hover .bar-rz { opacity: 1; background: rgba(255,255,255,.4); }
.card.is-bar .port { z-index: 3; }   /* ports above handles so linking still works */
/* On a bar the left/right edges are resize handles — link only from top/bottom
   ports so the two gestures don't clash (bar→bar lines auto-route finish→start
   regardless of which port you start from). */
.card.is-bar .port.pL, .card.is-bar .port.pR { display: none; }
/* top/bottom ports keep Lattice's default hover-reveal (opacity 0 → 1 on
   .card:hover) — they should vanish like normal nodes, not sit static. */
.card.is-bar.done { background: #2f8f57; border-color: #46b06f; }
.card.is-bar.done .ttl { text-decoration: line-through; opacity: .85; }
.card.is-bar.done-held { opacity: .8; }
.card.is-bar.sel { outline: 2px solid #60a5fa; outline-offset: 1px; }

/* ---- inspector colour swatches (settings pane) ---- */
#iColorSection .crow { display: flex; flex-wrap: wrap; gap: 6px; padding-top: 4px; }
#iColorSection .cswatch {
  width: 22px; height: 22px; padding: 0; border-radius: 6px; cursor: pointer;
  border: 2px solid transparent; box-shadow: 0 0 0 1px #0006 inset;
}
#iColorSection .cswatch.on { border-color: #fff; box-shadow: 0 0 0 1px #000; }
#iColorSection .cswatch.none {
  background: repeating-linear-gradient(45deg, #2a2f3a 0 4px, #171b22 4px 8px);
}
#iColorSection .cswatch.custom {
  position: relative; overflow: hidden;
  background: conic-gradient(#ef4444, #eab308, #22c55e, #14b8a6, #3b82f6, #a855f7, #ec4899, #ef4444);
}
#iColorSection .cswatch.custom input { position: absolute; inset: -6px; opacity: 0; cursor: pointer; }

/* ---- Gantt bar→bar dependency line (Finish→Start elbow + arrowhead) ---- */
.edge.dep-bar { stroke: #9db8d6; stroke-width: 1.4; fill: none; stroke-linejoin: round; opacity: .7; }
.edge.dep-bar.dim { opacity: .26; }

/* day-count badges: inside-bar chip + spilled-label suffix + inspector readout */
.card.is-bar .bar-days {
  flex: 0 0 auto; margin-left: 6px; font-size: 10px; font-weight: 700;
  opacity: .72; color: var(--bar-fg, #fff); pointer-events: none;
}
.bar-out-label .od { font-size: 10px; font-weight: 700; opacity: .7; }
#iScheduleSection .sched-dur { margin-top: 8px; font-size: 12px; color: #a9b2bf; }
#iScheduleSection .sched-dur b { color: #e7e9ee; font-variant-numeric: tabular-nums; }

/* compact dependency handle: day-gap pill + hover-reveal delete (declutters the
   old ···✕ pill on dense timelines, and shows days between linked tasks) */
.dep-handle {
  position: absolute; transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; gap: 2px;
  background: rgba(13, 15, 18, .82); border: 1px solid #2b3a4a; border-radius: 9px;
  padding: 1px 5px; font: 700 10px system-ui, -apple-system, sans-serif;
  color: #9db8d6; white-space: nowrap; pointer-events: auto;
}
.dep-handle:hover { border-color: #3a5068; background: rgba(13, 15, 18, .95); }
.dep-handle .dh-gap { cursor: pointer; }
.dep-handle .dh-x {
  display: none; border: 0; background: transparent; color: #e0808c;
  cursor: pointer; font-size: 10px; line-height: 1; padding: 0 0 0 2px;
}
.dep-handle:hover .dh-x { display: inline; }
/* back-to-back link: no number → just a small joint dot; expands on hover */
.dep-handle.dep-dot { background: transparent; border-color: transparent; padding: 3px; }
.dep-handle.dep-dot .dh-gap { width: 6px; height: 6px; border-radius: 50%; background: #7c8ea3; cursor: pointer; }
.dep-handle.dep-dot:hover { background: rgba(13, 15, 18, .92); border-color: #3a5068; padding: 1px 5px; }
.dep-handle.dep-dot:hover .dh-gap { width: auto; height: auto; background: transparent; }

/* concurrent (overlapping) tasks: amber "∥" pill + dashed connector */
.dep-handle .dh-gap.concurrent { color: #f0b429; font-size: 12px; }
.edge.dep-bar.concurrent { stroke: #f0b429; stroke-dasharray: 4 4; opacity: .85; }
.edge.dep-bar.behind { stroke: #ef4444; opacity: .8; }
.dep-handle .dh-gap.behind { color: #ef6a6a; }

/* pin toggle on container headers (gantt + section) — dim/grayscale when off */
.card.gantt .g-pin, .card.section .sec-pin {
  background: transparent; border: 0; cursor: pointer; font-size: 13px; line-height: 1;
  padding: 2px 5px; border-radius: 5px; opacity: .38; filter: grayscale(1);
}
.card.section .sec-pin { margin-left: auto; }
.card.gantt .g-pin:hover, .card.section .sec-pin:hover { opacity: .7; background: #ffffff14; }
.card.gantt .g-pin.on, .card.section .sec-pin.on { opacity: 1; filter: none; background: #ffffff1f; }

/* ---- top-bar hamburger menu (all canvas actions collapsed into a dropdown) ---- */
.menu-wrap { position: relative; display: inline-flex; }
.menu-btn { font-size: 18px; line-height: 1; padding: 6px 13px; }
.menu-dd {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 600;
  display: flex; flex-direction: column; gap: 4px;
  background: #11151b; border: 1px solid #2b3a4a; border-radius: 10px;
  padding: 6px; min-width: 178px; box-shadow: 0 14px 34px -8px #000b;
}
.menu-dd .btn { width: 100%; text-align: left; justify-content: flex-start; }

/* help popup (canvas tips, opened from the menu's Help button) */
.help-pop {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 700;
  width: 300px; padding: 12px 14px;
  background: #11151b; border: 1px solid #2b3a4a; border-radius: 10px;
  box-shadow: 0 14px 34px -8px #000b; color: #cbd5e1; font-size: 12.5px; line-height: 1.5;
}
.help-pop .help-title { font-weight: 700; color: #e7edf4; margin-bottom: 8px; font-size: 13px; }
.help-pop ul { margin: 0; padding-left: 16px; display: flex; flex-direction: column; gap: 4px; }
.help-pop .x {
  position: absolute; top: 8px; right: 8px; border: 0; background: transparent;
  color: #7c8aa0; cursor: pointer; font-size: 13px; line-height: 1;
}
.help-pop .x:hover { color: #e7edf4; }

/* ---- Live presence cursors on the public share ---- */
#cursors { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 55; }
.cursor { position: absolute; top: 0; left: 0; will-change: transform; }
.cursor svg { fill: var(--cur, #3aa0ff); filter: drop-shadow(0 1px 1.5px rgba(0,0,0,.45)); display: block; }
.cursor .cur-name {
  position: absolute; left: 14px; top: 12px; white-space: nowrap;
  background: var(--cur, #3aa0ff); color: #fff; font: 600 11px/1.5 system-ui, sans-serif;
  padding: 1px 7px; border-radius: 9px; box-shadow: 0 1px 3px rgba(0,0,0,.35);
}
#me-badge {
  position: fixed; left: 14px; bottom: 14px; z-index: 60; display: flex; align-items: center; gap: 7px;
  background: rgba(15,23,32,.86); color: #e8eef5; font: 600 12px system-ui, sans-serif;
  padding: 6px 11px; border-radius: 20px; border: 1px solid rgba(255,255,255,.12);
  backdrop-filter: blur(6px); pointer-events: none;
}
#me-badge .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--cur, #3aa0ff); box-shadow: 0 0 0 2px rgba(255,255,255,.15); }
#me-badge .me-you { opacity: .55; font-weight: 500; }
/* Owner (private) canvas never shows presence chrome. */
body:not(.share-mode) #cursors, body:not(.share-mode) #me-badge { display: none; }

/* ---- Read-only public share: hide all edit affordances ---- */
body.share-readonly .port,
body.share-readonly .bar-rz,
body.share-readonly .g-resize,
body.share-readonly .g-add,
body.share-readonly .g-pin,
body.share-readonly .g-mode { display: none !important; }
body.share-readonly .card.is-bar,
body.share-readonly .card.gantt { cursor: default; }
/* Small "view only" badge so visitors know the board can't be changed. */
body.share-readonly #ro-badge {
  position: fixed; right: 14px; bottom: 14px; z-index: 60;
  background: rgba(15,23,32,.85); color: #cfd8e3; font: 600 12px system-ui, sans-serif;
  padding: 6px 11px; border-radius: 20px; border: 1px solid rgba(255,255,255,.12);
  pointer-events: none;
}
body:not(.share-readonly) #ro-badge { display: none; }

/* ---- Draggable dependency-line centre handle ---- */
.dep-handle { cursor: grab; }
.dep-handle.dragging { cursor: grabbing; }
.dep-handle.dragging .dh-gap { box-shadow: 0 0 0 2px rgba(120,170,255,.6); }
.dep-handle .dh-x { cursor: pointer; }

/* ---- Split-screen reference shelf (second embedded canvas) ---- */
body.split #stage { right: 42%; }
#splitPane { position: fixed; inset: 52px 0 0 auto; width: 42%; display: none; flex-direction: column;
  background: #0b0f14; border-left: 2px solid #22303c; z-index: 30; }
body.split #splitPane { display: flex; }
#splitBar { height: 30px; flex: none; display: flex; align-items: center; justify-content: space-between;
  padding: 0 10px; background: #0f1720; border-bottom: 1px solid #22303c;
  font: 600 12px system-ui, sans-serif; color: #cfd8e3; }
#splitBar .x { background: none; border: 0; color: #7c8aa0; cursor: pointer; font-size: 14px; line-height: 1; }
#splitBar .x:hover { color: #e7edf4; }
#shelfFrame { flex: 1; width: 100%; border: 0; background: #0b0f14; }
/* Inside the shelf iframe: hide chrome, canvas fills the frame. */
body.pane-mode .bar, body.pane-mode #inbox { display: none; }
body.pane-mode #stage { inset: 0 !important; }
body.pane-mode #btnSplit, body.share-mode #btnSplit { display: none; }
/* Drop highlight while dragging a node over a canvas. */
#stage.drop-target::after { content: ""; position: absolute; inset: 0; z-index: 40; pointer-events: none;
  background: rgba(90,150,255,.10); border: 2px dashed rgba(120,170,255,.65); }

/* Cross-canvas drag grips (Gantt header + normal cards) — visible only in
   split/shelf mode. -webkit-user-drag:element is REQUIRED on macOS/WebKit for a
   non-anchor element's draggable=true to actually initiate a native drag. */
.g-move, .card-move { display: none; cursor: grab; background: none; border: 0; color: #9fb0c4;
  font-size: 14px; line-height: 1; padding: 0 6px 0 2px;
  -webkit-user-drag: element; user-select: none; -webkit-user-select: none; }
.g-move:hover, .card-move:hover { color: #fff; }
.g-move:active, .card-move:active { cursor: grabbing; }
body.split .g-move, body.pane-mode .g-move,
body.split .card-move, body.pane-mode .card-move { display: inline-flex; align-items: center; }
/* Card grip sits at the card's top-left, clear of the title and ports. */
.card-move { position: absolute; top: 1px; left: 4px; z-index: 4; }

/* Highlight the shelf pane while a drag hovers over it (it'll land there). */
#splitPane.drop-hot { outline: 3px solid rgba(120,170,255,.75); outline-offset: -3px; }
#splitPane.drop-hot #splitBar { background: #14324f; }
