/* The board itself: boxes, members, link knobs, wires. */

.wire {
  fill: none;
  stroke-width: 1.75;
  opacity: 0.8;
  pointer-events: stroke;
  cursor: pointer;
}
.wire:hover {
  opacity: 1;
  stroke-width: 2.75;
}
.wire-hit {
  fill: none;
  stroke: transparent;
  stroke-width: 16;
  pointer-events: stroke;
  cursor: pointer;
}

.box {
  position: absolute;
  width: max-content;
  min-width: 186px;
  max-width: 400px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 7px;
  outline: 1.5px solid transparent;
  outline-offset: 2px;
  transition: outline-color 0.12s;
}
.box.sel {
  outline-color: var(--accent);
}
.box.hinted {
  outline-color: var(--type);
}

.hd {
  display: flex;
  align-items: baseline;
  gap: 7px;
  padding: 8px 11px 7px;
  font-family: "IBM Plex Mono", monospace;
  border-bottom: 1px solid var(--border);
}
/* The keyword doubles as the box's drag handle. */
.kw {
  font-size: 11.5px;
  color: var(--faint);
  flex-shrink: 0;
  cursor: grab;
  padding: 2px 3px;
  margin: -2px -1px -2px -3px;
  border-radius: 3px;
}
.kw:hover {
  background: rgba(255, 255, 255, 0.05);
  color: var(--dim);
}
.kw:active {
  cursor: grabbing;
}
.nm {
  background: none;
  border: none;
  outline: none;
  padding: 0;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--accent);
  min-width: 40px;
}
.nm::placeholder {
  color: var(--faint);
  font-weight: 400;
}

.rows {
  padding: 3px 0;
}
.row {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 3px 11px;
  font-family: "IBM Plex Mono", monospace;
  position: relative;
}
.row:hover {
  background: rgba(255, 255, 255, 0.022);
}

.f {
  background: none;
  border: none;
  outline: none;
  padding: 0;
  font-family: inherit;
  font-size: 12px;
  min-width: 26px;
}
.f-name {
  color: var(--text);
}
.f-type {
  color: var(--type);
}
.f::placeholder {
  color: var(--faint);
}
.sep {
  color: var(--faint);
  font-size: 11.5px;
  flex-shrink: 0;
}

/* One knob per linkable slot, stacked beside the row. */
.knobs {
  margin-left: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  flex-shrink: 0;
  align-self: stretch;
}
.knob {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 1.5px solid var(--accent);
  background: var(--bg);
  cursor: crosshair;
  flex-shrink: 0;
  opacity: 0;
  transition:
    opacity 0.12s,
    transform 0.1s;
}
.row:hover .knob,
.box.sel .knob,
.row:focus-within .knob {
  opacity: 0.65;
}
.knob:hover {
  opacity: 1 !important;
  background: var(--accent);
  transform: scale(1.5);
}
.knob.wired {
  opacity: 1;
  background: var(--accent);
}

.empty {
  padding: 7px 11px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  color: var(--faint);
}

/* ---------- inheritance ---------- */

/* Inheritance carries one colour of its own rather than the endpoints'
   accents, so a family is recognisable without reading the boxes. */
.wire-ext {
  stroke: var(--inherit);
  stroke-width: 2;
}
/* The hollow triangle at the base end — the UML mark for inheritance. */
.wire-arrow {
  fill: var(--bg);
  stroke: var(--inherit);
  stroke-width: 1.75;
  opacity: 0.85;
  pointer-events: none;
}

/* The base-class knob is a diamond, so it never reads as one more slot. */
.knob-ext {
  margin-left: auto;
  align-self: center;
  border-radius: 1px;
  transform: rotate(45deg);
  border-color: var(--inherit);
}
.knob-ext:hover,
.knob-ext.wired {
  background: var(--inherit);
}
.knob-ext:hover {
  transform: rotate(45deg) scale(1.5);
}
.box:hover .knob-ext,
.box.sel .knob-ext,
.hd:focus-within .knob-ext {
  opacity: 0.65;
}

/* `class Dog : Animal` — the base named inline in the header. */
.ext {
  font-size: 11.5px;
  opacity: 0.75;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 1;
  min-width: 0;
}

/* A link the model refused: a cycle, or an enum at one end. */
@keyframes reject-flash {
  0%,
  100% {
    outline-color: transparent;
  }
  20%,
  60% {
    outline-color: var(--danger);
  }
}
.box.reject {
  animation: reject-flash 0.42s ease;
}

/* ---------- inherited (ghost) members ---------- */

/* Members a box gets from its base: shown so the box reads as the whole
   shape of the type, dimmed and italic so it is clear they are borrowed,
   and plain spans rather than inputs so there is no second place to edit
   the same field. */
.row.ghost {
  padding-top: 2px;
  padding-bottom: 2px;
  cursor: default;
}
.row.ghost:hover {
  background: none;
}
.g {
  font-size: 12px;
  font-style: italic;
  opacity: 0.5;
  white-space: nowrap;
}
.g-name {
  color: var(--text);
}
.g-type {
  color: var(--type);
}

/* A rule under the last borrowed row, dividing inherited from declared. */
.row.ghost-last {
  border-bottom: 1px dashed var(--border);
  margin-bottom: 3px;
  padding-bottom: 5px;
}

/* Marks a member that shadows an inherited name. The inherited row is
   suppressed in that case, so the weight is the only sign of the base. */
.row.overriding .f-name,
.row.overriding .f-type {
  font-weight: 700;
}
