/* Mesh & Gradient Studio — a split: the preview card on the left, the
   inspector and the CSS output on the right (layout from
   styles/components/form.css). Only the title tile, the stage and its nodes,
   the colour-stop rows' contents and the code block are the page's own. */

.mg-title-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(145deg, #FF6CAB, #7366FF);
  color: #fff;
}

/* ── Stage ──────────────────────────────────────────────────────────────── */
/* Fills the flush row edge to edge (the row inherits the card corners). */
.mg-stage {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  touch-action: none;
  user-select: none;
}
.mg-preview {
  position: absolute;
  inset: 0;
  background: #000;
}
/* Procedural film grain — a tiny inline SVG turbulence, scaled up so the noise
   reads as fine grain, overlaid with `overlay` blend so it adds texture
   without washing out the colors. */
.mg-grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
  transition: opacity var(--duration-snap) var(--ease-standard);
}

.mg-nodes { position: absolute; inset: 0; }
.mg-nodes.hidden { display: none; }

.mg-node {
  position: absolute;
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  border-radius: 50%;
  background: var(--node-c, #fff);
  border: 2.5px solid rgba(255, 255, 255, 0.95);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35), inset 0 0 0 1px rgba(0, 0, 0, 0.18);
  cursor: grab;
  padding: 0;
  transition: transform var(--duration-snap) var(--ease-spring);
}
.mg-node:hover { transform: scale(1.12); }
.mg-node:focus-visible {
  outline: none;
  transform: scale(1.12);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35), 0 0 0 4px var(--accent-soft-strong);
}
.mg-node.is-dragging { cursor: grabbing; transform: scale(1.2); }

/* ── Colour stops: one row each (built by app.js) ───────────────────────── */
.mg-stop input[type="color"] {
  width: 40px;
  height: 32px;
  flex: 0 0 auto;
}
.mg-stop-hex {
  flex: 1;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text-dim);
  letter-spacing: -0.01em;
}
.mg-stop-del {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-fill);
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--duration-snap) var(--ease-standard), color var(--duration-snap) var(--ease-standard), border-color var(--duration-snap) var(--ease-standard);
}
.mg-stop-del:hover:not(:disabled) { background: var(--danger-soft); border-color: transparent; color: var(--danger); }
.mg-stop-del:disabled { opacity: 0.35; cursor: not-allowed; }

/* ── Output ─────────────────────────────────────────────────────────────── */
.mg-css { --code-output-max-h: 160px; user-select: all; }

/* Never squeeze a download button below its icon + label: when the pair
   doesn't fit side by side (longer ko/ja labels) the row wraps and each
   button fills its own line instead of one hanging short under the other. */
.mg-actions > .btn { min-width: max-content; }
