.graph-viewport {
  background-color: #111a20;
  background-image: radial-gradient(circle,#33465090 .75px,transparent .8px);
  overflow: hidden;
  outline: none;
  touch-action: none
}
.graph-world {
  position: absolute;
  left: 0;
  top: 0;
  width: 1px;
  height: 1px;
  transform-origin: 0 0;
  will-change: transform
}
.graph-wires {
  position: absolute;
  top: 0;
  left: 0;
  overflow: visible;
  pointer-events: none
}
.graph-wire {
  fill: none;
  stroke-width: 2;
  opacity: .52;
  pointer-events: stroke;
  cursor: crosshair
}
.graph-wire:hover {
  stroke-width: 4;
  opacity: 1
}
.graph-wire.pending {
  stroke: #c0f0d7;
  stroke-dasharray: 5 4;
  opacity: 1;
  pointer-events: none
}
.terrain-node {
  position: absolute;
  width: 178px;
  border: 1px solid #3a474f;
  border-top: 2px solid var(--node-color);
  border-radius: 6px;
  background: #202a30;
  box-shadow: 0 3px 10px #0004;
  user-select: none;
  overflow: visible
}
.terrain-node.selected {
  border: 1px solid #abdac7;
  border-top: 2px solid #bbeed8;
  box-shadow: 0 0 0 2px #8ed1b525,0 6px 16px #0004
}
.terrain-node.bypassed {
  opacity: .42
}
.terrain-node.is-output {
  background: #20312e
}
.node-header {
  height: 30px;
  display: flex;
  align-items: center;
  padding: 0 8px;
  gap: 6px;
  cursor: grab;
  border-bottom: 1px solid #ffffff06
}
.node-name {
  font-size: 11px;
  letter-spacing: -.1px;
  color: #d1dade;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1
}
.node-eye {
  width: 20px;
  height: 20px;
  color: #718991;
  opacity: .5
}
.node-eye svg {
  width: 12px;
  height: 12px
}
.terrain-node:hover .node-eye {
  opacity: 1
}
.node-preview {
  height: 64px;
  margin: 7px 9px 3px;
  position: relative;
  background: linear-gradient(150deg,#304a48,#1b282e);
  border-radius: 3px;
  overflow: hidden
}
.node-preview canvas {
  width: 100%;
  height: 100%;
  image-rendering: auto;
  display: block;
  opacity: .93
}
.node-preview-label {
  position: absolute;
  bottom: 3px;
  right: 4px;
  font-size: 6px;
  font-weight: 500;
  letter-spacing: .8px;
  color: #b9d2ce99;
  text-shadow: 0 1px 2px #0009;
  pointer-events: none
}
.port-row {
  height: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 2px
}
.port-button {
  height: 16px;
  padding: 0;
  position: relative;
  font-size: 9px;
  line-height: 1;
  color: #7f9ba7;
  gap: 6px;
  max-width: 47%
}
.port-button:hover {
  color: #d7e9e2;
  background: none!important
}
.port-button.in {
  justify-content: flex-start
}
.port-button.out {
  justify-content: flex-end;
  margin-left: auto
}
.port-dot {
  position: absolute;
  top: 4px;
  width: 7px;
  height: 7px;
  border: 1px solid #719eaf;
  border-radius: 50%;
  background: #1c282e;
  transition: .1s
}
.port-button.in .port-dot {
  left: -14px
}
.port-button.out .port-dot {
  right: -14px;
  background: var(--node-color);
  border-color: var(--node-color);
  box-shadow: 0 0 0 2px #141e24
}
.port-button:hover .port-dot {
  background: #b6e2ce;
  border-color: #e8fff4;
  box-shadow: 0 0 5px #a9d9be66;
  transform: scale(1.3)
}
.port-spacer {
  flex: 1
}
.port-label {
  white-space: nowrap
}
.node-state {
  font-size: 6px;
  color: #44675d
}
.terrain-node[data-status=building] .node-state {
  color: #ead091;
  animation: pulse 1s infinite
}
.terrain-node[data-status=done] .node-state,.terrain-node[data-status=cached] .node-state {
  color: #8bd4b5
}
.graph-minimap {
  position: absolute;
  width: 139px;
  height: 68px;
  bottom: 10px;
  right: 10px;
  border: 1px solid #54706355;
  border-radius: 4px;
  opacity: .74;
  cursor: crosshair;
  box-shadow: 0 2px 8px #0003
}
.graph-minimap:hover {
  opacity: 1
}
.graph-viewport.panning {
  cursor: grabbing
}
@media(max-width:700px) {
  .graph-minimap {
    width: 105px;
    height: 51px
  }
}
