/* ==========================================================================
   Mermaid Studio — diagrams-as-code. Layout mirrors Code Genie: a toolbar, a
   split body (editor | preview), an error bar and a status footer. Uses the
   shared design tokens from protium-ui.css.
   ========================================================================== */

.ms-title { font-weight: 600; color: var(--text); letter-spacing: .2px; }

.ms-main {
  display: flex; flex-direction: column;
  height: calc(100vh - var(--nav-h) - var(--status-h));
  min-height: 0;
}

/* Each mode (Code / Draw) is itself a flex column filling .ms-main */
.ms-mode { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.ms-mode.pt-hidden { display: none; }

/* Disabled Draw tab in the segmented control */
.pt-segment button:disabled { opacity: .45; cursor: not-allowed; }
.pt-segment button:disabled:hover { color: var(--text-muted); }

/* ---- shape palette (draggable chips, Lucidchart-style) ---------------- */
/* DRAW body: left palette sidebar + canvas (Lucidchart/Miro layout) */
.ms-draw-row { flex: 1 1 auto; display: flex; min-height: 0; }
.ms-palette {
  flex: 0 0 168px; display: flex; flex-direction: column; gap: 6px;
  padding: 10px; overflow: auto; background: var(--surface); border-right: 1px solid var(--border);
}
.ms-palette-title { font: 600 11px/1 var(--font-sans); letter-spacing: .4px; text-transform: uppercase; color: var(--text-muted); padding: 2px 2px 6px; }
.ms-chip {
  display: flex; align-items: center; gap: 8px; cursor: grab;
  height: 34px; padding: 0 12px; border-radius: var(--r-md, 8px);
  border: 1px solid var(--border); background: var(--field); color: var(--text);
  font: 500 12.5px/1 var(--font-sans); user-select: none; white-space: nowrap;
  transition: border-color .12s var(--ease), background .12s var(--ease), box-shadow .12s var(--ease);
}
.ms-chip:hover { border-color: var(--accent); background: var(--surface); box-shadow: 0 1px 6px rgba(37,99,235,.12); }
.ms-chip:active { cursor: grabbing; }
/* tiny shape glyph to hint each chip's look */
.ms-chip-glyph { width: 16px; height: 12px; flex: 0 0 16px; border: 1.5px solid #2563eb; background: #eff6ff; }
.cg-rect { border-radius: 2px; }
.cg-round { border-radius: 5px; }
.cg-stadium { border-radius: 999px; }
.cg-subroutine { border-left-width: 3px; border-right-width: 3px; border-radius: 1px; }
.cg-cylinder { border-radius: 50% / 30%; }
.cg-circle { width: 13px; height: 13px; flex-basis: 13px; border-radius: 50%; }
.cg-diamond { width: 11px; height: 11px; flex-basis: 11px; transform: rotate(45deg); border-radius: 1px; }
.cg-hexagon { clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%); }

/* ---- DRAW canvas (React Flow) ----------------------------------------- */
/* Kept LIGHT in both themes — matches the preview canvas convention. The
   React Flow pane fills the area below the draw toolbar. */
.ms-rf {
  flex: 1 1 auto; min-height: 0; min-width: 0;
  background:
    radial-gradient(circle at 1px 1px, #e2e8f0 1px, transparent 0) 0 0 / 22px 22px,
    #ffffff;
}

/* The bundle renders each node as <div class="rf-node rf-<shape>"> holding a
   .rf-label, with four .rf-h connection handles. */
.rf-node {
  padding: 10px 16px; border: 1.5px solid #2563eb; background: #eff6ff;
  border-radius: 8px; font: 600 13px var(--font-sans); color: #0f172a;
  min-width: 96px; text-align: center; cursor: grab;
}
.rf-node:active { cursor: grabbing; }
/* Selection: make it OBVIOUS (was a thin 2px ring that was easy to miss, so
   users weren't sure a box was selected before pressing Delete). A thicker ring
   + soft glow reads clearly as "this is selected, it'll be deleted". */
.rf-node.is-sel {
  box-shadow: 0 0 0 3px var(--accent), 0 0 0 6px rgba(37,99,235,.18);
  border-color: var(--accent);
}
.rf-node.rf-round { border-radius: 18px; }
.rf-node.rf-stadium { border-radius: 999px; }
.rf-node.rf-subroutine { border-left: 4px double #2563eb; border-right: 4px double #2563eb; }
.rf-node.rf-cylinder { border-radius: 50% / 16px; }
.rf-node.rf-circle {
  border-radius: 50%; width: 84px; height: 84px;
  display: flex; align-items: center; justify-content: center; min-width: 0;
}
.rf-node.rf-diamond {
  width: 84px; height: 84px; display: flex; align-items: center;
  justify-content: center; transform: rotate(45deg); border-radius: 6px; min-width: 0;
}
.rf-node.rf-diamond .rf-label { transform: rotate(-45deg); }
.rf-node.rf-hexagon { clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%); padding: 14px 24px; }

/* Handles hidden until the box is hovered/selected, so the body is the clear
   drag target and connecting (drag from a dot) is deliberate.
   IMPORTANT: React Flow marks source handles `.connectionindicator`, which sets
   `pointer-events: all` on them. With opacity:0 alone the invisible 10px dots on
   each edge still hit-test, so pressing near a node edge starts a *connection*
   instead of *moving* the node — that's the "dragging felt buggy" report. Force
   `pointer-events:none` while hidden so the body is the unambiguous drag target;
   restore `pointer-events:all` only once the dots are revealed (hover/selected),
   keeping deliberate connect-by-dragging intact. */
/* ---- connect hit-areas (item 3): full-side EDGE strips ------------------
   Each source handle is rendered as a thin strip running the full length of a
   side, so a connection can be started by grabbing ANYWHERE along that edge —
   not just a tiny dot. Hidden + pointer-events:none until the node is hovered/
   selected, so the BODY remains the unambiguous MOVE target; only on hover do
   the strips light up and become grabbable. A small visible dot is drawn via
   ::after for affordance. The target handle (rf-h-target) covers the whole node
   so released connections / onConnectEnd can land anywhere on the box. */
.rf-h {
  background: transparent; border: none; border-radius: 0;
  opacity: 0; pointer-events: none !important;
  transition: opacity .12s var(--ease), background .12s var(--ease);
  z-index: 5;
}
/* strip geometry per side — thin band hugging each edge (override RF inline) */
.rf-h-t, .rf-h-b { width: 100% !important; height: 12px !important; left: 0 !important; transform: none !important; min-width: 0 !important; }
.rf-h-t { top: -2px !important; } .rf-h-b { bottom: -2px !important; top: auto !important; }
.rf-h-l, .rf-h-r { width: 12px !important; height: 100% !important; top: 0 !important; transform: none !important; min-height: 0 !important; }
.rf-h-l { left: -2px !important; } .rf-h-r { right: -2px !important; left: auto !important; }
/* visible affordance dot centered on each strip — a crisp, clearly-grabbable
   "connection point" (Lucidchart/Miro style). Bigger + white halo so it reads as
   an obvious target on hover; grows on its own hover for clear "grab here" intent. */
.rf-h::after {
  content: ""; position: absolute; width: 11px; height: 11px; border-radius: 50%;
  background: #2563eb; border: 2.5px solid #fff;
  box-shadow: 0 0 0 1.5px rgba(37,99,235,.55), 0 1px 3px rgba(15,23,42,.25);
  transition: transform .1s var(--ease), background .1s var(--ease);
}
.rf-h-t::after, .rf-h-b::after { left: 50%; top: 50%; transform: translate(-50%, -50%); }
.rf-h-l::after, .rf-h-r::after { left: 50%; top: 50%; transform: translate(-50%, -50%); }
/* reveal on hover/selected: strips become grabbable and the dots show.
   cursor:crosshair across the WHOLE strip (not just the tiny dot) so the entire
   side reads as "grab to connect". */
.rf-node:hover .rf-h, .react-flow__node:hover .rf-h, .react-flow__node.selected .rf-h {
  opacity: 1; pointer-events: all !important; cursor: crosshair;
}
/* hovering a strip: tint it and pop the dot so it's unmistakably the grab point */
.rf-node:hover .rf-h:hover, .react-flow__node:hover .rf-h:hover {
  background: rgba(37,99,235,.12); cursor: crosshair;
}
.rf-node:hover .rf-h:hover::after, .react-flow__node:hover .rf-h:hover::after {
  transform: translate(-50%, -50%) scale(1.35); background: #1d4ed8;
}

/* ---- connection-drag drop-target highlighting -------------------------- */
/* While a connection is being dragged (wrapper gets .rf-connecting from
   entry.jsx onConnectStart/End), EVERY box advertises that it can receive the
   edge (dots shown), and the box currently under the pointer lights up green so
   the user can SEE where the edge will land. Combined with the generous 90px
   auto-connect threshold, dropping near a box reliably connects. */
.rf-connecting .rf-h { opacity: 1; }
.rf-connecting .react-flow__node:hover .rf-node,
.rf-connecting .rf-node:hover {
  box-shadow: 0 0 0 3px #16a34a, 0 0 0 8px rgba(22,163,74,.22);
  border-color: #16a34a; background: #f0fdf4;
}
/* whole canvas shows crosshair during a connection drag for clear intent */
.rf-connecting .react-flow__pane { cursor: crosshair; }
/* whole-node target handle: invisible, sits under the body, accepts drops */
.rf-h-target {
  width: 100% !important; height: 100% !important; top: 0 !important; left: 0 !important;
  transform: none !important; min-width: 0 !important; min-height: 0 !important;
  background: transparent; border: none; border-radius: 8px; opacity: 0;
  pointer-events: none !important; z-index: 0;
}

/* ---- inline label editing (item 5) ------------------------------------ */
.rf-label-input {
  font: 600 13px var(--font-sans); color: #0f172a; text-align: center;
  border: 1px solid #2563eb; border-radius: 4px; background: #fff;
  padding: 2px 6px; width: 100%; min-width: 70px; box-sizing: border-box; outline: none;
}
.rf-node.rf-diamond .rf-label-input { transform: rotate(-45deg); }
/* While editing, the input must be the unambiguous focus/click target: lift it
   above the connection handles and disable their pointer-events so a click can't
   land on a handle (starting a connection drag) instead of the field. */
.rf-label-input { position: relative; z-index: 10; pointer-events: auto; }
.rf-node.is-editing .rf-h,
.rf-node.is-editing .rf-h-target { pointer-events: none !important; opacity: 0 !important; }

/* ---- orthogonal edge labels (Yes/No etc.), centered on the elbow path ----
   Rendered via EdgeLabelRenderer as an HTML chip so it sits crisply on the
   right-angle midpoint, regardless of solid/dotted/thick line style. */
.rf-edge-label {
  font: 600 11px var(--font-sans); color: #334155;
  background: #fff; border: 1px solid #e2e8f0; border-radius: 6px;
  padding: 1px 6px; line-height: 1.4; white-space: nowrap;
  box-shadow: 0 1px 2px rgba(15,23,42,.08); user-select: none;
}

/* ---- reaflow-style hover "+ add connected node" affordance (item 3) ------
   A small round button anchored to the node's bottom-right. Hidden until the
   node is hovered; clicking adds a connected child + opens inline rename. */
.rf-add-child {
  position: absolute; right: -11px; bottom: -11px; z-index: 11;
  width: 22px; height: 22px; border-radius: 50%;
  border: 1.5px solid #2563eb; background: #2563eb; color: #fff;
  font: 700 15px/1 var(--font-sans); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transform: scale(.6); pointer-events: none;
  transition: opacity .12s ease, transform .12s ease;
  box-shadow: 0 2px 6px rgba(37,99,235,.35);
}
.rf-node:hover .rf-add-child,
.react-flow__node:hover .rf-add-child,
.react-flow__node.selected .rf-add-child {
  opacity: 1; transform: scale(1); pointer-events: all;
}
.rf-add-child:hover { background: #1d4ed8; transform: scale(1.12); }
/* keep the "+" upright on rotated diamonds */
.rf-node.rf-diamond .rf-add-child { transform: rotate(-45deg) scale(.6); right: 2px; bottom: 2px; }
.react-flow__node:hover .rf-node.rf-diamond .rf-add-child,
.rf-node.rf-diamond:hover .rf-add-child { transform: rotate(-45deg) scale(1); }
/* don't show "+" while editing the label */
.rf-node.is-editing .rf-add-child { display: none; }

/* ---- React Flow chrome: edges, Controls, MiniMap ----------------------
   The official @xyflow stylesheet (vendor/reactflow.css) IS loaded, but its
   default theme is tuned for a grey canvas. On our WHITE canvas the controls
   (#fefefe bg, #eee borders) and minimap nodes (#e2e2e2) almost vanish, and
   the default edge stroke (#b1b1b7) is faint. We tune the documented CSS
   variables + a few element rules so edges read crisply and the bottom-left
   Controls and bottom-right MiniMap look like proper React Flow chrome. */
.ms-rf .react-flow {
  /* crisper, slightly darker edges + arrowheads (Lucidchart-like) */
  --xy-edge-stroke-default: #64748b;
  --xy-edge-stroke-selected-default: #2563eb;
  /* controls: white buttons, real border + shadow so they sit ON the canvas */
  --xy-controls-button-background-color-default: #ffffff;
  --xy-controls-button-background-color-hover-default: #eff6ff;
  --xy-controls-button-color-default: #334155;
  --xy-controls-button-color-hover-default: #2563eb;
  --xy-controls-button-border-color-default: #e2e8f0;
  --xy-controls-box-shadow-default: 0 2px 10px rgba(15, 23, 42, .14);
  /* minimap: white bg, clearly visible node fill + viewport mask */
  --xy-minimap-background-color-default: #ffffff;
  --xy-minimap-node-background-color-default: #bfdbfe;
  --xy-minimap-node-stroke-color-default: #2563eb;
  --xy-minimap-mask-background-color-default: rgba(37, 99, 235, .10);
  --xy-minimap-mask-stroke-color-default: rgba(37, 99, 235, .45);
}
/* give the Controls + MiniMap panels a rounded card look */
.ms-rf .react-flow__controls { border-radius: 8px; overflow: hidden; }
.ms-rf .react-flow__controls-button { border-bottom-color: #e2e8f0; }
.ms-rf .react-flow__minimap {
  border: 1px solid #e2e8f0; border-radius: 8px;
  box-shadow: 0 2px 10px rgba(15, 23, 42, .14);
}

/* ---- empty-state hint over the canvas (item 8) ------------------------- */
/* The hint is a SIBLING of #rf inside .ms-rf-wrap (React Flow owns #rf's
   children, so the hint can't live inside it). The wrapper is the flex cell;
   #rf fills it and the hint overlays it, centered. Toggled via inline display
   by studio.js based on node count. */
.ms-rf-wrap { flex: 1 1 auto; min-height: 0; min-width: 0; position: relative; display: flex; }
.ms-rf-wrap .ms-rf { flex: 1 1 auto; }
.rf-empty-hint {
  display: none; position: absolute; inset: 0; z-index: 4; pointer-events: none;
  align-items: center; justify-content: center; text-align: center; padding: 24px;
  color: #94a3b8; font: 500 14px/1.7 var(--font-sans);
}

/* ---- toolbar ----------------------------------------------------------- */
.ms-toolbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 16px; background: var(--surface); border-bottom: 1px solid var(--border);
}
.ms-toolbar .sep { width: 1px; height: 22px; background: var(--border); margin: 0 2px; }
.ms-toolbar .spacer { flex: 1 1 auto; }

/* Export trio (PNG / SVG / PDF) grouped as one cohesive, labelled cluster so the
   three download actions read as a set, set apart from the file actions. */
.ms-export-grp {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 8px 4px 10px; border-radius: 10px;
  border: 1px solid var(--border-faint); background: var(--field);
}
.ms-grp-label {
  font: 600 10px/1 var(--font-sans); letter-spacing: .5px; text-transform: uppercase;
  color: var(--text-faint); margin-right: 2px; user-select: none;
}

/* ---- DRAW color control (FEATURE 2): preset swatches + reset + custom ---- */
.ms-color {
  display: inline-flex; align-items: center; gap: 5px;
  height: 34px; padding: 0 8px 0 10px; border-radius: var(--r-md);
  border: 1px solid var(--border); background: var(--field);
}
.ms-color-label {
  font: 600 10px/1 var(--font-sans); letter-spacing: .5px; text-transform: uppercase;
  color: var(--text-faint); margin-right: 2px; user-select: none;
}
.ms-sw {
  width: 20px; height: 20px; padding: 0; border-radius: 5px; cursor: pointer;
  background: var(--sw-fill, #eff6ff); border: 1.5px solid var(--sw-stroke, #2563eb);
  transition: transform .1s var(--ease), box-shadow .1s var(--ease);
}
.ms-sw:hover { transform: scale(1.12); box-shadow: 0 0 0 2px rgba(37,99,235,.18); }
.ms-sw-reset {
  background: #fff; border: 1.5px dashed #94a3b8; color: #64748b;
  font: 700 13px/1 var(--font-sans); display: inline-flex; align-items: center; justify-content: center;
}
.ms-sw-custom {
  position: relative; overflow: hidden; padding: 0;
  border: 1.5px solid var(--border); background:
    conic-gradient(from 0deg, #ef4444, #f59e0b, #22c55e, #06b6d4, #6366f1, #a855f7, #ef4444);
}
.ms-sw-custom input[type=color] {
  position: absolute; inset: -4px; width: calc(100% + 8px); height: calc(100% + 8px);
  border: none; padding: 0; background: transparent; cursor: pointer; opacity: 0;
}

.ms-select {
  height: 34px; padding: 0 30px 0 12px; border-radius: var(--r-md);
  border: 1px solid var(--border); background: var(--field); color: var(--text);
  font: 500 13px/1 var(--font-sans); cursor: pointer; appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2390a0b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat: no-repeat; background-position: right 8px center;
}
.ms-select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }

/* file-open is a <label> styled as a button; hide the native input */
#btn-open { cursor: pointer; }

.ms-status { display: flex; align-items: center; gap: 10px; }
.ms-meta { color: var(--text-faint); font: 500 12px/1 var(--font-mono); white-space: nowrap; }

/* ---- body: editor | grip | preview ------------------------------------ */
.ms-body { flex: 1 1 auto; display: flex; min-height: 0; }

.ms-cm { flex: 1 1 0; min-width: 280px; overflow: hidden; position: relative; }
.ms-cm .CodeMirror { height: 100%; font: 13px/1.6 var(--font-mono); }

.ms-grip {
  flex: 0 0 6px; cursor: col-resize; background: var(--border-faint);
  transition: background .15s var(--ease);
}
.ms-grip:hover, .ms-grip.is-active { background: var(--accent); }

.ms-preview {
  flex: 1 1 0; min-width: 320px; display: flex; flex-direction: column;
  background: var(--surface-2); border-left: 1px solid var(--border);
}
.ms-preview-head {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-bottom: 1px solid var(--border); background: var(--surface);
}
.ms-preview-title { font: 600 12px/1 var(--font-sans); letter-spacing: .4px; text-transform: uppercase; color: var(--text-muted); }
.ms-preview-head .spacer { flex: 1 1 auto; }
/* Zoom controls as a tidy segmented cluster sitting in the preview header */
.ms-zoom {
  display: flex; align-items: center; gap: 2px;
  padding: 3px; border-radius: 9px;
  border: 1px solid var(--border-faint); background: var(--field);
}
.ms-zoom .pt-btn { min-width: 30px; justify-content: center; font-weight: 600; }
/* live zoom-level readout sitting between the − / + buttons */
.ms-zoom-level {
  min-width: 42px; text-align: center; padding: 0 4px;
  font: 600 11.5px/1 var(--font-mono); color: var(--text-muted);
  letter-spacing: .2px; user-select: none; white-space: nowrap;
}

/* the stage holds the rendered SVG; svg-pan-zoom drives pan & wheel-zoom.
   Kept LIGHT in both themes: Mermaid's default theme draws dark edges/arrows,
   which vanish on a dark canvas — and a white canvas matches the exported image.
   The diagram is auto-fit + centered on every render (see fitAndFrame() in
   studio.js) so it reads as a centered document with margins, not a static SVG
   stranded in a corner. A subtle inset shadow frames the canvas as a surface.
   touch-action:none keeps wheel / pinch zoom on the canvas instead of letting
   the page scroll hijack it. */
.ms-stage {
  flex: 1 1 auto; min-height: 0; position: relative; overflow: hidden;
  touch-action: none;
  background:
    radial-gradient(circle at 1px 1px, #e2e8f0 1px, transparent 0) 0 0 / 22px 22px,
    #ffffff;
}
/* soft inner vignette so the canvas reads as a framed surface, not a flat fill */
.ms-stage::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 1;
  box-shadow: inset 0 0 0 1px rgba(15,23,42,.05), inset 0 14px 32px -22px rgba(15,23,42,.18);
}
.ms-stage #render { width: 100%; height: 100%; display: block; position: relative; z-index: 0; }
.ms-stage svg { width: 100%; height: 100%; display: block; cursor: grab; }
.ms-stage svg:active { cursor: grabbing; }

/* empty / placeholder */
.ms-stage.is-empty::after {
  content: "Your diagram will appear here.";
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: #94a3b8; font: 500 14px/1 var(--font-sans);
}

/* ---- error bar --------------------------------------------------------- */
.ms-error {
  display: none; align-items: center; gap: 8px;
  padding: 8px 16px; background: var(--bad-soft); border-top: 1px solid var(--bad-border);
  color: var(--bad); font: 500 12.5px/1.5 var(--font-mono); white-space: pre-wrap;
}
.ms-error.is-show { display: flex; }
.ms-error svg { width: 16px; height: 16px; flex: 0 0 16px; }

/* ---- CodeMirror theme: .cm-s-protium (shared with Code Genie) ---------- */
.cm-s-protium.CodeMirror { background: var(--field); color: #d4d4d4; }
.cm-s-protium .CodeMirror-gutters { background: var(--field); border-right: 1px solid var(--border); }
.cm-s-protium .CodeMirror-linenumber { color: var(--text-faint); }
.cm-s-protium .CodeMirror-cursor { border-left: 1.5px solid #aed6ff; }
.cm-s-protium .CodeMirror-activeline-background { background: rgba(255,255,255,0.03); }
.cm-s-protium .CodeMirror-selected { background: var(--accent-soft) !important; }
.cm-s-protium .CodeMirror-focused .CodeMirror-selected { background: var(--accent-soft) !important; }
.cm-s-protium .cm-string { color: #ce9178; }
.cm-s-protium .cm-keyword { color: #c586c0; }
.cm-s-protium .cm-atom { color: #569cd6; }
.cm-s-protium .cm-number { color: #b5cea8; }
.cm-s-protium .cm-operator { color: #4ec9b0; }
.cm-s-protium .cm-variable-2 { color: #9cdcfe; }
.cm-s-protium .cm-comment { color: #6a9955; }
.cm-s-protium .cm-error { color: var(--bad); }

@media (max-width: 760px) {
  .ms-body { flex-direction: column; }
  .ms-grip { display: none; }
  .ms-cm, .ms-preview { min-width: 0; }
  .ms-preview { border-left: none; border-top: 1px solid var(--border); }
}
