@use "../../../../wc";

:host {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.viewport {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background-color: rgb(var(--zn-color-body));
  background-image: radial-gradient(rgb(var(--zn-color-border)) 1px, transparent 1px);
  background-size: 20px 20px; // matches GRID_SIZE — positions snap to these dots
  cursor: grab;
  touch-action: none;

  // During a move/pan drag, force grabbing across the canvas and its notes.
  // (The dragged node card is handled inside its own shadow via [dragging].)
  &.grabbing,
  &.grabbing * {
    cursor: grabbing !important;
  }

  &.connecting,
  &.connecting * {
    cursor: crosshair !important;
  }

  &.resizing,
  &.resizing * {
    cursor: nwse-resize !important;
  }

  // While a stray branch is live, everything is either a target (a node) or a cancel.
  &.linking {
    cursor: crosshair;
  }

  // While dragging a step, emphasise every "+" so the drop targets are obvious.
  &.step-dragging .add-point {
    color: rgb(var(--zn-panel));
    background: rgb(var(--zn-color-primary));
    border-style: solid;
    box-shadow: 0 0 0 4px color-mix(in srgb, rgb(var(--zn-color-primary)) 22%, transparent);
  }
}

.connections {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;

  .wire {
    fill: none;
    stroke: rgb(var(--zn-color-primary));
    stroke-width: 2;

    &--stub {
      stroke: rgb(var(--zn-color-border-active));
      stroke-dasharray: 4 4;
    }

    // The stray branch following the cursor while picking a node to attach to.
    &--preview {
      stroke-dasharray: 6 4;
    }

    // A wire that loops back to an earlier step — solid amber, so return paths
    // stand out from the forward flow.
    &--loop {
      stroke: rgb(var(--zn-color-warning));
    }
  }

  marker path {
    fill: rgb(var(--zn-color-primary));
  }

  marker#flow-arrow-loop path {
    fill: rgb(var(--zn-color-warning));
  }
}

.add-point {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  margin: -12px; // centre on the transformed point
  padding: 0;
  border-radius: 50%;
  color: rgb(var(--zn-color-primary));
  background: rgb(var(--zn-panel));
  border: 1px dashed rgb(var(--zn-color-border-active));
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;

  &:hover {
    color: rgb(var(--zn-panel));
    background: rgb(var(--zn-color-primary));
    border-style: solid;
  }

  &--target {
    color: rgb(var(--zn-panel));
    background: rgb(var(--zn-color-primary));
    border-style: solid;
    box-shadow: 0 0 0 4px color-mix(in srgb, rgb(var(--zn-color-primary)) 25%, transparent);
  }

  &--wire {
    width: 20px;
    height: 20px;
    margin: -10px;
  }
}

.layer {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 0 0;
  width: 0;
  height: 0;
}

.node-pos {
  position: absolute;
  top: 0;
  left: 0;
}

// Branch names rendered as a clickable pill on their branch; the wire drops
// into the pill's top and continues from its bottom. Clicking opens the editor;
// hovering slides out a delete button to the right.
.branch-pill {
  display: flex;
  align-items: center;
  justify-content: center;
  // Size to the text, hard-wrapping at PILL_MAX_WIDTH — width: max-content
  // stops overflow-wrap: anywhere collapsing the shrink-wrapped pill to a
  // single character column. Height is intrinsic: fixed padding around
  // 20px lines (one line = 40px tall, matching PILL_HEIGHT).
  width: max-content;
  max-width: 240px;
  box-sizing: border-box;
  text-align: center;
  overflow-wrap: anywhere;
  overflow: hidden;
  padding: 0 18px;
  border-radius: 10px; // matches the node cards
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  // After the font shorthand, which would reset it — matches PILL_LINE_HEIGHT
  // so wrapped lines track the estimated pill height.
  line-height: 20px;
  color: rgb(var(--zn-text));
  background: color-mix(in srgb, rgb(var(--zn-color-primary)) 8%, rgb(var(--zn-panel)));
  border: 1px solid color-mix(in srgb, rgb(var(--zn-color-primary)) 45%, transparent);
  cursor: pointer;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;

  &:hover {
    border-color: rgb(var(--zn-color-primary));
    box-shadow: 0 1px 3px rgba(var(--zn-shadow), 0.4);
  }

  &--selected {
    border-color: rgb(var(--zn-color-primary));
    background: color-mix(in srgb, rgb(var(--zn-color-primary)) 16%, rgb(var(--zn-panel)));
  }

  // A loop branch — amber to match its return wire.
  &--loop {
    background: color-mix(in srgb, rgb(var(--zn-color-warning)) 10%, rgb(var(--zn-panel)));
    border-color: color-mix(in srgb, rgb(var(--zn-color-warning)) 55%, transparent);

    &:hover {
      border-color: rgb(var(--zn-color-warning));
    }

    &.branch-pill--selected {
      border-color: rgb(var(--zn-color-warning));
      background: color-mix(in srgb, rgb(var(--zn-color-warning)) 18%, rgb(var(--zn-panel)));
    }
  }

  &-wrap {
    position: absolute;
    top: 0;
    left: 0;
    transform: translateX(-50%);
    display: flex;
    align-items: stretch;

    // Invisible bridge so the cursor can travel from the pill to the delete
    // button without the hover (and the button) disappearing.
    &::after {
      content: '';
      position: absolute;
      left: 100%;
      top: 0;
      width: 40px;
      height: 100%;
    }

    // The reveal is slightly delayed so pills that shift under a stationary
    // cursor (e.g. re-spreading after a sibling branch is deleted) don't flash
    // their delete button; hiding stays immediate.
    &:hover .branch-pill-delete {
      opacity: 1;
      transform: translate(0, -50%);
      pointer-events: auto;
      transition-delay: 0.15s;
    }
  }

  // An orphaned branch's output port, on the pill's bottom edge — click to
  // start a stray branch continuing from the pill, just like a node's port.
  &-port {
    position: absolute;
    z-index: 1;
    left: 50%;
    bottom: 0;
    transform: translate(-50%, 50%);
    width: 11px;
    height: 11px;
    box-sizing: border-box;
    border-radius: 50%;
    background: rgb(var(--zn-panel));
    border: 2px solid rgb(var(--zn-color-primary));
    cursor: pointer;
    transition: transform 0.12s ease, box-shadow 0.12s ease;

    &:hover {
      transform: translate(-50%, 50%) scale(1.35);
      box-shadow: 0 0 0 4px color-mix(in srgb, rgb(var(--zn-color-primary)) 20%, transparent);
    }
  }

  // Slides out from behind the pill on hover; deletes the branch and its wire.
  // Sits above the wrap's ::after hover bridge, which would otherwise swallow
  // clicks (and the pointer cursor).
  &-delete {
    position: absolute;
    z-index: 1;
    left: calc(100% + 8px);
    top: 50%;
    transform: translate(-10px, -50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgb(var(--zn-color-error));
    color: white;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;

    &:hover {
      filter: brightness(1.1);
    }
  }
}

// Placeholder shown while dragging a step over the canvas — previews
// the step that will be created, so you can see what and where it lands.
.drop-ghost {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 12px;
  border: 2px dashed rgb(var(--zn-color-primary));
  border-radius: 10px;
  background: color-mix(in srgb, rgb(var(--zn-color-primary)) 10%, rgb(var(--zn-panel)));
  opacity: 0.9;
  pointer-events: none;

  &__icon {
    --node-accent: rgb(var(--zn-color-primary));
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border-radius: 8px;
    color: var(--node-accent);
    background: color-mix(in srgb, var(--node-accent) 16%, rgb(var(--zn-panel)));
  }

  &__label {
    font-size: 0.8125rem;
    font-weight: 600;
    color: rgb(var(--zn-text));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

.toolbar {
  position: absolute;
  top: 16px;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  background: rgb(var(--zn-panel));
  border: 1px solid rgb(var(--zn-border-color));
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(var(--zn-shadow), 0.4);
  z-index: 2;

  &--history {
    left: 16px;
  }

  &--zoom {
    right: 16px;
  }
}

// Delete drop-zone, bottom-right while a node or step is being dragged.
.bin {
  position: absolute;
  right: 16px;
  bottom: 16px;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 12px;
  color: rgb(var(--zn-color-muted-text));
  background: rgb(var(--zn-panel));
  border: 1px dashed rgb(var(--zn-color-border-active));
  box-shadow: 0 1px 3px rgba(var(--zn-shadow), 0.4);
  transition: background 0.12s ease, color 0.12s ease, transform 0.12s ease;

  &--over {
    color: rgb(var(--zn-panel));
    background: rgb(var(--zn-color-error));
    border-style: solid;
    border-color: rgb(var(--zn-color-error));
    transform: scale(1.12);
  }
}

.note {
  position: absolute;
  display: flex;
  flex-direction: column;
  background: #fef9c3;
  border: 1px solid #fde68a;
  border-radius: 4px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);

  &__resize {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 16px;
    height: 16px;
    cursor: nwse-resize;
    // Visual corner grip.
    background: linear-gradient(135deg, transparent 0 50%, #d9c64a 50% 60%, transparent 60% 70%, #d9c64a 70% 80%, transparent 80%);
  }

  &__bar {
    display: flex;
    justify-content: flex-end;
    height: 20px;
    cursor: grab;
  }

  &__close {
    width: 20px;
    height: 20px;
    padding: 0;
    font-size: 14px;
    line-height: 1;
    color: #92400e;
    background: transparent;
    cursor: pointer;
  }

  &__text {
    flex: 1;
    margin: 0;
    padding: 0 10px 10px;
    resize: none;
    border: none;
    outline: none;
    background: transparent;
    font: inherit;
    font-size: 0.8125rem;
    color: #713f12;
  }
}
