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

:host {
  @include wc.scrollbars; // styles scrollbars of all descendant scroll areas (steps panel, inspector, sidebar, picker)
  display: block;
  width: 100%;
  height: 100%;
  min-height: 480px;
  color: rgb(var(--zn-text));
}

.builder {
  --steps-width: 343px;
  --side-width: 500px;

  display: grid;
  grid-template-columns: var(--steps-width) minmax(0, 1fr) var(--side-width);
  grid-template-rows: auto minmax(0, 1fr);
  width: 100%;
  height: 100%;
  background: rgb(var(--zn-panel));
  border: 1px solid rgb(var(--zn-border-color));
  border-radius: 8px;
  overflow: hidden;
  transition: grid-template-columns 0.2s ease;

  // Side panels tuck away via the canvas-edge chevrons. Their padding and
  // border would floor the width above zero, so those collapse too.
  &--steps-collapsed {
    --steps-width: 0px;

    .steps {
      border-right: none;
    }
  }

  &--side-collapsed {
    --side-width: 0px;

    .sidebar,
    .inspector {
      padding: 0;
      border-left: none;
    }
  }
}

// Full-width action bar above the three panels; hidden unless actions are slotted.
.header {
  grid-row: 1;
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid rgb(var(--zn-border-color));
  background: rgb(var(--zn-panel));

  &[hidden] {
    display: none;
  }

  &__group {
    display: flex;
    align-items: center;
    gap: 8px;
  }
}

// The panels sit on the second grid row explicitly — the hidden header leaves
// the grid entirely (display: none), so auto-placement would pull them into the
// `auto` first row and collapse the builder to its content height.
.steps,
.inspector,
.sidebar {
  grid-row: 2;
  display: flex;
  flex-direction: column;
  min-height: 0;
  // Clip cleanly while the column animates to zero width.
  min-width: 0;
  overflow: hidden;
  background: rgb(var(--zn-panel));
}

.canvas-cell {
  grid-row: 2;
  position: relative;
  min-width: 0;
  min-height: 0;
}

// Chevrons straddling the canvas edges — tuck a side panel away / bring it back.
.panel-toggle {
  position: absolute;
  top: 50%;
  z-index: 6;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border-radius: 50%;
  color: rgb(var(--zn-color-muted-text));
  background: rgb(var(--zn-panel));
  border: 1px solid rgb(var(--zn-border-color));
  box-shadow: 0 1px 3px rgba(var(--zn-shadow), 0.4);
  cursor: pointer;
  transition: left 0.2s ease, right 0.2s ease, color 0.12s ease, border-color 0.12s ease;

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

  &--left {
    left: -12px;

    // With the panel tucked away, sit fully inside the canvas.
    &.panel-toggle--tucked {
      left: 8px;
    }
  }

  &--right {
    right: -12px;

    &.panel-toggle--tucked {
      right: 8px;
    }
  }
}

// --- Steps panel (left column) -----------------------------------------------

.steps {
  // Colour the slotted zn-navbar's active tab to match the steps panel surface,
  // rather than the navbar's default body colour.
  --zn-active-nav-background: var(--zn-panel);

  border-right: 1px solid rgb(var(--zn-border-color));

  // The registry-driven steps panel fills the column below the title block.
  &-content {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }

  // Each tab panel fills the zn-tabs content area and lets its category list scroll.
  &-panel {
    display: flex;
    flex-direction: column;
    min-height: 0;
    height: 100%;
  }

  // Per-tab hint, shown beneath the tab bar with a divider before the categories.
  &-hint {
    margin: 0;
    padding: 12px var(--zn-base-gap);
    font-size: 0.8125rem;
    line-height: 1.4;
    color: rgb(var(--zn-color-muted-text));
  }

  &-scroll {
    @include wc.scrollbars;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding-bottom: 16px;

    // Divider above every category (and between the hint/tabs and the first one).
    zn-flow-step-group {
      display: block;
      border-top: 1px solid rgb(var(--zn-border-color));
    }
  }

  &-uncategorized {
    padding: 8px var(--zn-base-gap);
  }

  &-empty {
    padding: 16px var(--zn-base-gap);
    font-size: 0.8125rem;
    color: rgb(var(--zn-color-muted-text));
  }
}

// Slotted <zn-flow-step>s are type declarations only — never displayed.
.declarations {
  display: none;
}

.title-block {
  padding: 16px;
  border-bottom: 1px solid rgb(var(--zn-border-color));

  .heading {
    font-size: 0.9375rem;
    font-weight: 600;
  }

  .subheading {
    margin-top: 2px;
    font-size: 0.75rem;
    color: rgb(var(--zn-color-muted-text));
  }
}

.search {
  padding: 12px 12px 8px;
}

.step {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  margin-bottom: 6px;
  background: rgb(var(--zn-panel));
  border: 1px solid rgb(var(--zn-border-color));
  border-radius: 8px;
  font-size: 0.8125rem;
  cursor: grab;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;

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

  &:active {
    cursor: grabbing;
  }

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

  &__label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

// --- Inspector (right column while a node / branch is selected) ---------------

.inspector {
  border-left: 1px solid rgb(var(--zn-border-color));
  // The editor slides in from the right when a node or branch is selected.
  animation: inspector-in 0.18s ease;

  &-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    height: 100%;
    padding: 24px;
    text-align: center;
    color: rgb(var(--zn-color-muted-text));
    font-size: 0.8125rem;
  }

  &-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px;
    border-bottom: 1px solid rgb(var(--zn-border-color));

    &__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) 14%, transparent);
    }

    // Long labels truncate rather than pushing the close button out of the panel.
    &__text {
      flex: 1;
      min-width: 0;
    }

    // Title + badges (e.g. the Loop tag) on one line: the title shrinks with an
    // ellipsis while the badge always stays visible.
    &__title-row {
      display: flex;
      align-items: center;
      gap: 6px;
      min-width: 0;

      .inspector-head__title {
        min-width: 0;
      }
    }

    &__title {
      font-size: 0.875rem;
      font-weight: 600;
    }

    &__title,
    &__type {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    &__type {
      font-size: 0.75rem;
      color: rgb(var(--zn-color-muted-text));
    }
  }

  &-body {
    @include wc.scrollbars;
    display: flex;
    flex-direction: column;
    gap: 14px;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 16px;
  }

  &-hint {
    margin: 0;
    font-size: 0.75rem;
    color: rgb(var(--zn-color-muted-text));
  }

  // Marks a loop branch in the editor head, matching its amber pill and wire.
  &-loop-tag {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    gap: 3px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1;
    color: rgb(var(--zn-color-warning));
    background: color-mix(in srgb, rgb(var(--zn-color-warning)) 14%, transparent);
  }

  &-close {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    margin-left: auto;
    width: 28px;
    height: 28px;
    padding: 0;
    border-radius: 6px;
    color: rgb(var(--zn-color-muted-text));
    background: transparent;
    cursor: pointer;

    &:hover {
      background: rgb(var(--zn-color-tab));
      color: rgb(var(--zn-text));
    }
  }
}

@keyframes inspector-in {
  from {
    transform: translateX(32px);
    opacity: 0.3;
  }

  to {
    transform: translateX(0);
    opacity: 1;
  }
}

// --- Sidebar (right rail: status / errors / version history) ------------------

.sidebar {
  @include wc.scrollbars;
  border-left: 1px solid rgb(var(--zn-border-color));
  overflow-y: auto;
  padding: 16px;

  &-section__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
    font-size: 0.8125rem;
    font-weight: 600;
  }

  &-count {
    min-width: 20px;
    padding: 0 6px;
    font-size: 0.75rem;
    line-height: 18px;
    text-align: center;
    border-radius: 9px;
    color: rgb(var(--zn-color-muted-text));
    background: rgb(var(--zn-color-tab));
  }

  &-empty {
    margin: 0;
    font-size: 0.75rem;
    color: rgb(var(--zn-color-muted-text));
  }

  &-error {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    margin-bottom: 6px;
    padding: 8px 10px;
    font-size: 0.8125rem;
    text-align: left;
    color: rgb(var(--zn-color-error));
    background: color-mix(in srgb, rgb(var(--zn-color-error)) 7%, transparent);
    border: 1px solid color-mix(in srgb, rgb(var(--zn-color-error)) 25%, transparent);
    border-radius: 8px;
    cursor: pointer;
  }
}

// --- "+" picker popover ------------------------------------------------------

.picker {
  position: fixed;
  z-index: 21;
  width: 220px;
  max-height: 320px;
  overflow-y: auto;
  padding: 6px;
  background: rgb(var(--zn-panel));
  border: 1px solid rgb(var(--zn-border-color));
  border-radius: 8px;
  box-shadow: 0 6px 24px rgba(var(--zn-shadow), 0.5);
  @include wc.scrollbars;

  &-backdrop {
    position: fixed;
    inset: 0;
    z-index: 20;
  }

  &-group {
    padding: 8px 8px 4px;
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: rgb(var(--zn-color-muted-text));
  }

  &-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 7px 8px;
    font-size: 0.8125rem;
    text-align: left;
    background: transparent;
    border-radius: 6px;
    cursor: pointer;

    &:hover {
      background: rgb(var(--zn-color-tab));
    }

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

  &-empty {
    margin: 0;
    padding: 10px;
    font-size: 0.75rem;
    color: rgb(var(--zn-color-muted-text));
  }
}

// --- Auto-save overlays --------------------------------------------------------

// Bottom-left status pill: flashes green as a save lands, then keeps a quiet
// "last saved Xm ago".
.save-status {
  position: absolute;
  left: 16px;
  bottom: 16px;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  font-size: 0.75rem;
  color: rgb(var(--zn-color-muted-text));
  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);
  pointer-events: none;
  transition: color 0.15s ease, border-color 0.15s ease;

  &--saved {
    color: rgb(var(--zn-color-success));
    border-color: color-mix(in srgb, rgb(var(--zn-color-success)) 45%, transparent);
  }
}

// Top-centre prompt offering a differing auto-saved draft after a load.
.restore-banner {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  display: flex;
  align-items: center;
  // On a narrow canvas the message keeps sensible line lengths and the
  // buttons wrap below it, instead of squeezing to a word per line.
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  width: max-content;
  max-width: calc(100% - 32px);
  padding: 8px 12px;
  font-size: 0.8125rem;
  color: rgb(var(--zn-text));
  background: rgb(var(--zn-panel));
  border: 1px solid rgb(var(--zn-border-color));
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(var(--zn-shadow), 0.5);

  span {
    flex: 1 1 auto;
    min-width: min(160px, 100%);
  }

  button {
    flex: 0 0 auto;
    padding: 3px 10px;
    font-size: 0.75rem;
    font-weight: 600;
    border-radius: 6px;
    cursor: pointer;
  }

  &__restore {
    color: rgb(var(--zn-panel));
    background: rgb(var(--zn-color-primary));

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

  &__dismiss {
    color: rgb(var(--zn-color-muted-text));
    background: transparent;

    &:hover {
      background: rgb(var(--zn-color-tab));
    }
  }
}

// --- Move banner -------------------------------------------------------------

.move-banner {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  font-size: 0.8125rem;
  color: rgb(var(--zn-panel));
  background: rgb(var(--zn-color-primary));
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(var(--zn-shadow), 0.5);

  button {
    padding: 2px 8px;
    font-size: 0.75rem;
    font-weight: 600;
    color: rgb(var(--zn-panel));
    background: rgba(255, 255, 255, 0.2);
    border-radius: 6px;
    cursor: pointer;
  }
}
