/* noodles — minimal node-graph editor for the Noisemaker DSL.
 *
 * Every color / space / radius comes from handfish's --hf-* tokens
 * (tokens.css). The palette is pinned to dark via <html data-theme="dark">.
 * This sheet is intentionally lean: canvas, graph-layer placeholder, toolbar,
 * code drawer shell, loading wordmark, and the compile-error banner. */

/* Material Symbols icon font. Powers the toolbar's icon-button ligatures
 * (add / code / visibility_off / fullscreen) and the fullscreen icon swap.
 * handfish styles .hf-icon-btn chrome but does not ship the icon face. */
@font-face {
  font-family: 'Material Symbols Outlined';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url('https://fonts.noisefactor.io/fonts/material-symbols-outlined/material-symbols-outlined.woff2') format('woff2');
}

.material-symbols {
  font-family: var(--hf-font-family-icon), 'Material Symbols Outlined';
  font-weight: normal;
  font-style: normal;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased;
  font-variation-settings: 'FILL' 0;
}

html,
body {
  margin: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--hf-color-1);
  color: var(--hf-text-normal);
  font-family: var(--hf-font-family);
}

/* Render surface — fills the viewport, sits behind everything. */
#canvas {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  display: block;
  background: var(--hf-color-1);
}

/* Node graph overlay. Covers the viewport and catches background pan/zoom;
 * the canvas keeps rendering beneath it (no click-through this task). */
#graph-layer {
  position: fixed;
  inset: 0;
  z-index: 10;
}

#graph-layer[hidden] {
  display: none;
}

/* Shared pan/zoom frame for the SVG edge layer + HTML node layer. Its children
 * are pointer-events:none so empty regions fall through to #graph-layer; .node
 * and .pin re-enable hits. */
#graph-viewport {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 0 0;
  pointer-events: none;
}

#edge-layer {
  position: absolute;
  top: 0;
  left: 0;
  overflow: visible; /* 0-size box; paths draw in graph coords beyond it */
  pointer-events: none;
}

#node-layer {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}

/* --- Nodes: glass panels, lowercase, --hf-* tokens only ------------------- */
.node {
  position: absolute;
  box-sizing: border-box;
  min-width: 8rem;
  display: flex;
  flex-direction: column;
  gap: var(--hf-space-1);
  padding: var(--hf-space-2);
  border-radius: var(--hf-radius);
  border: var(--hf-border-width) solid var(--hf-border);
  background: color-mix(in srgb, var(--hf-bg-surface) var(--hf-surface-opacity), transparent var(--hf-surface-transparency));
  backdrop-filter: var(--hf-glass-blur);
  -webkit-backdrop-filter: var(--hf-glass-blur);
  box-shadow: var(--hf-shadow-md);
  color: var(--hf-text-normal);
  font-family: var(--hf-font-family);
  font-size: var(--hf-size-sm);
  text-transform: lowercase;
  cursor: grab;
  user-select: none;
  pointer-events: auto;
}

.node.selected {
  outline: var(--hf-focus-ring-width) solid var(--hf-accent);
  outline-offset: var(--hf-focus-ring-offset);
}

.node-head {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--hf-space-2);
}

.node-title {
  flex: 1 1 auto;
  font-weight: 600;
}

.node-ns {
  flex: 0 0 auto;
}

.node-params {
  display: flex;
  flex-direction: column;
  gap: var(--hf-space-1);
}

.param-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--hf-space-2);
}

.param-name {
  flex: 1 1 auto;
  color: var(--hf-text-dim);
}

.param-value {
  flex: 0 0 auto;
  color: var(--hf-text-normal);
  font-family: var(--hf-font-family-mono);
}

.node-body {
  display: flex;
}

.node-body slider-value {
  flex: 1 1 auto;
}

/* Compact surface / render pills. */
.node-pill {
  flex-direction: row;
  align-items: center;
  gap: var(--hf-space-2);
  min-width: 0;
  padding: var(--hf-space-1) var(--hf-space-3);
  border-radius: var(--hf-radius-pill);
}

/* --- Pins: 10px circles, color-coded by lane ----------------------------- */
.pin {
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  border-radius: var(--hf-radius-full);
  border: var(--hf-border-width) solid var(--hf-border);
  cursor: crosshair;
  pointer-events: auto;
}

.pin.flow {
  background: var(--hf-accent-3);
}

.pin.value {
  background: var(--hf-yellow);
}

.pin.droppable {
  outline: 2px solid var(--hf-accent);
  outline-offset: 1px;
}

/* In/out pins overhang the node edge; param pins hug the left edge of the row. */
.node-head .pin-in,
.node-pill .pin-in {
  margin-left: calc(-1 * var(--hf-space-2) - 5px);
}

.node-head .pin-out,
.node-pill .pin-out {
  margin-right: calc(-1 * var(--hf-space-2) - 5px);
}

.param-row .pin-param {
  position: absolute;
  left: calc(-1 * var(--hf-space-2) - 5px);
}

/* --- Edges: flow solid accent, value dashed yellow, ghost dashed accent --- */
.edge {
  fill: none;
  stroke-width: 2;
}

.edge.is-flow {
  stroke: color-mix(in oklab, var(--hf-accent) 60%, transparent);
}

.edge.is-value {
  stroke: var(--hf-yellow);
  stroke-dasharray: 6 4;
}

.edge-ghost {
  fill: none;
  stroke: var(--hf-accent);
  stroke-width: 2;
  stroke-dasharray: 6 4;
  opacity: 0.7;
}

/* Toolbar — glass panel pinned to the top-right corner. */
#toolbar {
  position: fixed;
  top: var(--hf-space-3);
  right: var(--hf-space-3);
  z-index: 20;
  gap: var(--hf-space-1);
  padding: var(--hf-space-1) var(--hf-space-2);
  border-radius: var(--hf-radius);
  background: color-mix(in srgb, var(--hf-bg-surface) var(--hf-surface-opacity), transparent var(--hf-surface-transparency));
  backdrop-filter: var(--hf-glass-blur);
  -webkit-backdrop-filter: var(--hf-glass-blur);
  border: var(--hf-border-width) solid var(--hf-border);
  box-shadow: var(--hf-shadow-lg);
}

/* Keyboard focus rings on the toolbar buttons + pins — tokenized, keyboard-only
 * (:focus-visible), so a mouse click never draws a ring. */
#toolbar button:focus-visible,
.pin:focus-visible {
  outline: var(--hf-focus-ring-width) solid var(--hf-focus-ring-color);
  outline-offset: var(--hf-focus-ring-offset);
}

/* Code drawer — right-side panel, glass surface. Shell only this task. */
#code-panel {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 15;
  display: flex;
  flex-direction: column;
  gap: var(--hf-space-2);
  width: 40%;
  height: 100%;
  padding: var(--hf-space-4);
  background: color-mix(in srgb, var(--hf-bg-surface) var(--hf-surface-opacity), transparent var(--hf-surface-transparency));
  backdrop-filter: var(--hf-glass-blur);
  -webkit-backdrop-filter: var(--hf-glass-blur);
  border-left: var(--hf-border-width) solid var(--hf-border);
}

#code-panel[hidden] {
  display: none;
}

/* Distraction-free: hide the chrome — toolbar, node graph, and code drawer. The
 * canvas sits outside these three containers, so it keeps rendering underneath.
 * The id+class selector out-specifies every rule that shows them, so no
 * !important is needed (none of the three is ever shown via an inline style). */
body.ui-hidden #toolbar,
body.ui-hidden #graph-layer,
body.ui-hidden #code-panel {
  display: none;
}

#dsl-editor {
  flex: 1 1 auto;
  min-height: 0;
}

/* Compile-error banner — lives inside the code drawer. */
#compile-error {
  flex: 0 0 auto;
  max-height: 40%;
  overflow-y: auto;
  padding: var(--hf-space-2) var(--hf-space-3);
  border-radius: var(--hf-radius-sm);
  border: var(--hf-border-width) solid var(--hf-red);
  background: var(--hf-color-2);
  color: var(--hf-red);
  font-family: var(--hf-font-family-mono);
  font-size: 0.8125rem;
  line-height: 1.45;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

#compile-error[hidden] {
  display: none;
}

/* Loading wordmark — centered, lowercase, fades out after first compile. */
#loading {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--hf-color-1);
  color: var(--hf-text-dim);
  font-size: var(--hf-size-xl);
  text-transform: lowercase;
  letter-spacing: 0.15em;
  transition: opacity 0.5s ease;
}

#loading.hidden {
  opacity: 0;
  pointer-events: none;
}
