/* Synthology.Shared.Web — synth-dataflow.css (RI-2026-138 Phase 1)
 *
 * Theme-aware styling for the shared Visual Dataflow renderer
 * (synth-dataflow.js). The diagram is hosted inside a per-product IFRAME
 * (e.g. SynthIQ /dataflow.html) which does NOT inherit the parent shell's
 * light/dark class — so this stylesheet adapts via prefers-color-scheme on
 * its own, defaulting to the dark surface the admin iframes use.
 *
 * The node palette is the SHARED semantic set (gray/teal/blue/green/amber/
 * red/indigo); a product's brand accent for "process" nodes arrives at
 * runtime as the --df-accent CSS variable set on the SVG root.
 *
 * Non-device per FD&C Act 520(o)(1)(D). */

:root {
  --df-bg: #0f1117;
  --df-fg: #e2e8f0;
  --df-muted: #94a3b8;
  --df-edge: #64748b;
  --df-edge-active: #94a3b8;
  --df-card: #161a28;
  --df-border: #2d3148;
  /* semantic node ramps: fill / stroke / text */
  --df-gray-f: #1e2333;   --df-gray-s: #3a4155;   --df-gray-t: #cbd5e1;
  --df-teal-f: rgba(20,184,166,.16);  --df-teal-s: #2dd4bf;  --df-teal-t: #99f6e4;
  --df-blue-f: rgba(59,130,246,.18);  --df-blue-s: #60a5fa;  --df-blue-t: #bfdbfe;
  --df-green-f: rgba(34,197,94,.16);  --df-green-s: #4ade80; --df-green-t: #bbf7d0;
  --df-amber-f: rgba(234,179,8,.16);  --df-amber-s: #facc15; --df-amber-t: #fde68a;
  --df-red-f: rgba(239,68,68,.16);    --df-red-s: #f87171;   --df-red-t: #fecaca;
  --df-indigo-f: rgba(99,102,241,.18);--df-indigo-s: #818cf8;--df-indigo-t: #c7d2fe;
  /* status dots */
  --df-ok: #22c55e; --df-warn: #eab308; --df-down: #ef4444; --df-idle: #64748b;
  /* focus highlight ring (RI-2026-138 deep-link focus) */
  --df-focus-ring: #f59e0b;
}

@media (prefers-color-scheme: light) {
  :root {
    --df-bg: #f8fafc;
    --df-fg: #0f172a;
    --df-muted: #64748b;
    --df-edge: #94a3b8;
    --df-edge-active: #475569;
    --df-card: #ffffff;
    --df-border: #e2e8f0;
    --df-gray-f: #f1f5f9;   --df-gray-s: #cbd5e1;   --df-gray-t: #0f172a;
    --df-teal-f: #ccfbf1;   --df-teal-s: #14b8a6;   --df-teal-t: #134e4a;
    --df-blue-f: #dbeafe;   --df-blue-s: #3b82f6;   --df-blue-t: #1e3a8a;
    --df-green-f: #dcfce7;  --df-green-s: #22c55e;  --df-green-t: #14532d;
    --df-amber-f: #fef9c3;  --df-amber-s: #eab308;  --df-amber-t: #713f12;
    --df-red-f: #fee2e2;    --df-red-s: #ef4444;    --df-red-t: #7f1d1d;
    --df-indigo-f: #e0e7ff; --df-indigo-s: #6366f1; --df-indigo-t: #312e81;
    --df-focus-ring: #d97706;
  }
}

/* ── App-theme override (RI-2026-305) ───────────────────────────────────────
   These pages render inside a same-origin <iframe> (Study Trace, Visual
   Dataflow) that does NOT inherit the parent shell's <html data-theme>, so the
   two rules above make the iframe follow the OS `prefers-color-scheme` instead
   of the app's light/dark/system toggle. synth-dataflow.js mirrors the shell's
   resolved data-theme onto THIS document's <html>; these explicit selectors
   (specificity 0,2,0) then win over the :root rules above (0,1,0) so an app
   choice of light/dark always applies, regardless of the OS setting.
     • data-theme="light"  → force light   • data-theme="dark" → force dark
     • data-theme="system" / no attribute  → fall through to the :root +
       prefers-color-scheme rules above and follow the OS (unchanged). */
:root[data-theme="dark"] {
  --df-bg: #0f1117;
  --df-fg: #e2e8f0;
  --df-muted: #94a3b8;
  --df-edge: #64748b;
  --df-edge-active: #94a3b8;
  --df-card: #161a28;
  --df-border: #2d3148;
  --df-gray-f: #1e2333;   --df-gray-s: #3a4155;   --df-gray-t: #cbd5e1;
  --df-teal-f: rgba(20,184,166,.16);  --df-teal-s: #2dd4bf;  --df-teal-t: #99f6e4;
  --df-blue-f: rgba(59,130,246,.18);  --df-blue-s: #60a5fa;  --df-blue-t: #bfdbfe;
  --df-green-f: rgba(34,197,94,.16);  --df-green-s: #4ade80; --df-green-t: #bbf7d0;
  --df-amber-f: rgba(234,179,8,.16);  --df-amber-s: #facc15; --df-amber-t: #fde68a;
  --df-red-f: rgba(239,68,68,.16);    --df-red-s: #f87171;   --df-red-t: #fecaca;
  --df-indigo-f: rgba(99,102,241,.18);--df-indigo-s: #818cf8;--df-indigo-t: #c7d2fe;
  --df-focus-ring: #f59e0b;
}

:root[data-theme="light"] {
  --df-bg: #f8fafc;
  --df-fg: #0f172a;
  --df-muted: #64748b;
  --df-edge: #94a3b8;
  --df-edge-active: #475569;
  --df-card: #ffffff;
  --df-border: #e2e8f0;
  --df-gray-f: #f1f5f9;   --df-gray-s: #cbd5e1;   --df-gray-t: #0f172a;
  --df-teal-f: #ccfbf1;   --df-teal-s: #14b8a6;   --df-teal-t: #134e4a;
  --df-blue-f: #dbeafe;   --df-blue-s: #3b82f6;   --df-blue-t: #1e3a8a;
  --df-green-f: #dcfce7;  --df-green-s: #22c55e;  --df-green-t: #14532d;
  --df-amber-f: #fef9c3;  --df-amber-s: #eab308;  --df-amber-t: #713f12;
  --df-red-f: #fee2e2;    --df-red-s: #ef4444;    --df-red-t: #7f1d1d;
  --df-indigo-f: #e0e7ff; --df-indigo-s: #6366f1; --df-indigo-t: #312e81;
  --df-focus-ring: #d97706;
}

.df-root {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--df-fg);
}

.df-tabs { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 14px; max-width: 100%; overflow-x: auto; }
.df-tab {
  padding: 6px 13px; background: var(--df-card); color: var(--df-muted);
  border: 1px solid var(--df-border); border-radius: 999px; font-size: 12.5px;
  font-weight: 600; cursor: pointer; white-space: nowrap;
}
.df-tab.active { color: var(--df-fg); border-color: var(--df-accent, #0074D2); }
.df-tab-select {
  padding: 6px 13px; background: var(--df-card); color: var(--df-fg);
  border: 1px solid var(--df-border); border-radius: 999px; font-size: 12.5px;
  font-weight: 600; cursor: pointer; max-width: 260px;
}
.df-tab-select.active { border-color: var(--df-accent, #0074D2); }

.df-scroll {
  width: 100%; overflow: auto; border: 1px solid var(--df-border);
  border-radius: 12px; background: var(--df-card); padding: 8px;
}

.df-svg { display: block; }

/* nodes — the <g class="df-node c-XXX"> wraps a <rect> + text */
.df-node rect.df-box { stroke-width: 1.5; rx: 9; }
.df-node text { font-family: inherit; }
.df-node .df-title { font-size: 13px; font-weight: 700; }
.df-node .df-sub { font-size: 11px; }

.df-node.c-gray   rect.df-box { fill: var(--df-gray-f);   stroke: var(--df-gray-s); }
.df-node.c-gray   .df-title, .df-node.c-gray   .df-sub { fill: var(--df-gray-t); }
.df-node.c-teal   rect.df-box { fill: var(--df-teal-f);   stroke: var(--df-teal-s); }
.df-node.c-teal   .df-title, .df-node.c-teal   .df-sub { fill: var(--df-teal-t); }
.df-node.c-blue   rect.df-box { fill: var(--df-blue-f);   stroke: var(--df-blue-s); }
.df-node.c-blue   .df-title, .df-node.c-blue   .df-sub { fill: var(--df-blue-t); }
.df-node.c-green  rect.df-box { fill: var(--df-green-f);  stroke: var(--df-green-s); }
.df-node.c-green  .df-title, .df-node.c-green  .df-sub { fill: var(--df-green-t); }
.df-node.c-amber  rect.df-box { fill: var(--df-amber-f);  stroke: var(--df-amber-s); }
.df-node.c-amber  .df-title, .df-node.c-amber  .df-sub { fill: var(--df-amber-t); }
.df-node.c-red    rect.df-box { fill: var(--df-red-f);    stroke: var(--df-red-s); }
.df-node.c-red    .df-title, .df-node.c-red    .df-sub { fill: var(--df-red-t); }
.df-node.c-indigo rect.df-box { fill: var(--df-indigo-f); stroke: var(--df-indigo-s); }
.df-node.c-indigo .df-title, .df-node.c-indigo .df-sub { fill: var(--df-indigo-t); }

/* process nodes carry the product brand accent (runtime --df-accent) */
.df-node.c-accent rect.df-box {
  fill: color-mix(in srgb, var(--df-accent, #0074D2) 16%, var(--df-card));
  stroke: var(--df-accent, #0074D2);
}
.df-node.c-accent .df-title { fill: var(--df-fg); }
.df-node.c-accent .df-sub { fill: var(--df-muted); }

/* edges */
.df-edge { fill: none; stroke: var(--df-edge); stroke-width: 1.5; }
.df-edge.active { stroke: var(--df-edge-active); }
.df-edge.dashed { stroke-dasharray: 5 4; }
.df-edge-label { fill: var(--df-muted); font-size: 10px; font-style: italic; }

/* status dot (top-right of node) */
.df-dot-ok { fill: var(--df-ok); }
.df-dot-warn { fill: var(--df-warn); }
.df-dot-down { fill: var(--df-down); }
.df-dot-idle { fill: var(--df-idle); }
.df-dot-unknown { fill: var(--df-idle); }

/* legend */
.df-legend { display: flex; flex-wrap: wrap; gap: 14px; margin: 12px 2px 0; }
.df-legend .li { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--df-muted); }
.df-legend .sw { width: 12px; height: 12px; border-radius: 3px; border: 1px solid var(--df-border); }
.df-legend .sw.c-gray { background: var(--df-gray-s); }
.df-legend .sw.c-teal { background: var(--df-teal-s); }
.df-legend .sw.c-blue { background: var(--df-blue-s); }
.df-legend .sw.c-green { background: var(--df-green-s); }
.df-legend .sw.c-amber { background: var(--df-amber-s); }
.df-legend .sw.c-red { background: var(--df-red-s); }
.df-legend .sw.c-indigo { background: var(--df-indigo-s); }
.df-legend .sw.c-accent { background: var(--df-accent, #0074D2); }

.df-msg { color: var(--df-muted); font-size: 13px; padding: 30px; text-align: center;
  border: 1px dashed var(--df-border); border-radius: 12px; }
.df-msg.err { color: var(--df-red-s); }

/* focus deep-link (RI-2026-138): highlight origin node(s), dim the rest,
   trace the up/down flow, with a "show only this flow" toggle. */
.df-halo { fill: none; stroke: var(--df-focus-ring); stroke-width: 2.5; }
.df-node.df-focus rect.df-box { stroke-width: 2.5; }
.df-node.df-dim { opacity: .16; }
.df-edge.df-dim { opacity: .1; }
.df-edge-label.df-dim { opacity: .1; }

.df-focus-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  margin: 0 2px 10px; padding: 8px 12px; background: var(--df-card);
  border: 1px solid var(--df-border); border-left: 3px solid var(--df-focus-ring);
  border-radius: 10px; font-size: 12.5px; color: var(--df-muted); }
.df-focus-bar .df-focus-label b { color: var(--df-fg); font-weight: 700; }
.df-focus-toggle { display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  color: var(--df-fg); user-select: none; }
.df-focus-toggle input { accent-color: var(--df-focus-ring); }
.df-focus-clear { margin-left: auto; padding: 4px 11px; background: transparent;
  color: var(--df-muted); border: 1px solid var(--df-border); border-radius: 999px;
  font-size: 12px; cursor: pointer; }
.df-focus-clear:hover { color: var(--df-fg); border-color: var(--df-focus-ring); }

/* ════════════════════════════════════════════════════════════════════════
   RI-2026-138 Phase 2 (DCR-2026-887): editable canvas — edit toolbar, the
   click-to-edit node affordance, and the create/edit modal. All scoped to the
   shared --df-* palette so it themes with the diagram (light/dark via
   prefers-color-scheme). The modal overlay is appended to <body> (covers the
   iframe viewport); --df-accent isn't on :root so its primary button falls
   back to the default blue — intentional.
   ════════════════════════════════════════════════════════════════════════ */

/* Edit toolbar */
.df-edit-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin: 0 2px 12px; }
.df-edit-toggle { padding: 6px 14px; background: var(--df-card); color: var(--df-fg);
  border: 1px solid var(--df-border); border-radius: 999px; font-size: 12.5px;
  font-weight: 600; cursor: pointer; }
.df-edit-toggle:hover { border-color: var(--df-accent, #0074D2); }
.df-edit-toggle.on { background: var(--df-accent, #0074D2); color: #fff;
  border-color: var(--df-accent, #0074D2); }
.df-edit-hint { font-size: 12px; color: var(--df-muted); }
.df-edit-add { padding: 5px 12px; background: transparent; color: var(--df-fg);
  border: 1px dashed var(--df-border); border-radius: 999px; font-size: 12px;
  font-weight: 600; cursor: pointer; }
.df-edit-add:hover { border-color: var(--df-accent, #0074D2); border-style: solid; }

/* RI-2026-138 Phase 5 (DCR-2026-893): DRAFT/STAGING toolbar — Save / Discard / banner. */
.df-edit-save { padding: 6px 14px; background: var(--df-accent, #0074D2); color: #fff;
  border: 1px solid var(--df-accent, #0074D2); border-radius: 999px; font-size: 12.5px;
  font-weight: 700; cursor: pointer; }
.df-edit-save:hover { filter: brightness(1.05); }
.df-edit-save:disabled { opacity: .6; cursor: default; }
.df-edit-discard { padding: 6px 13px; background: transparent; color: var(--df-red-s, #dc2626);
  border: 1px solid var(--df-red-s, #dc2626); border-radius: 999px; font-size: 12.5px;
  font-weight: 600; cursor: pointer; }
.df-edit-discard:hover { background: var(--df-red-f, rgba(239,68,68,.08)); }
.df-edit-savemsg { font-size: 12px; font-weight: 600; color: var(--df-green-s, #16a34a); }
.df-edit-savemsg.err { color: var(--df-red-s, #dc2626); }

/* Staged (unsaved) nodes + edges: dashed outline + accent tint so the operator sees
   exactly what a Save would commit. */
.df-node.df-node-staged rect.df-box { stroke-dasharray: 5 3; stroke-width: 2; }
.df-node.df-node-edited  rect.df-box { stroke-dasharray: 2 2; }
.df-edge.df-edge-staged { stroke-dasharray: 6 4; opacity: .85; }

/* Click-to-edit node affordance */
.df-node.df-editable { cursor: pointer; }
.df-node.df-editable rect.df-box { stroke-dasharray: none; }
.df-node.df-editable:hover rect.df-box { stroke-width: 2.5; filter: brightness(1.08); }

/* Modal (create / edit) */
.df-modal-overlay { position: fixed; inset: 0; z-index: 9999;
  background: rgba(8, 11, 18, .55); display: flex; align-items: flex-start;
  justify-content: center; padding: 6vh 16px 16px; overflow: auto; }
.df-modal { width: 100%; max-width: 460px; background: var(--df-bg);
  color: var(--df-fg); border: 1px solid var(--df-border); border-radius: 14px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .45); padding: 18px 20px 16px;
  font-size: 13px; }
.df-modal-title { font-size: 15px; font-weight: 700; margin: 0 0 12px; }
.df-modal-err { background: var(--df-red-f); color: var(--df-red-t);
  border: 1px solid var(--df-red-s); border-radius: 8px; padding: 7px 10px;
  font-size: 12.5px; margin: 0 0 12px; }

/* Form */
.df-form { display: flex; flex-direction: column; gap: 11px; }
.df-frow { display: flex; flex-direction: column; gap: 4px; }
.df-flabel { font-size: 12px; font-weight: 600; color: var(--df-muted); }
.df-fhelp { font-size: 11px; color: var(--df-muted); opacity: .85; }
.df-frow input[type=text], .df-frow input[type=number], .df-frow select,
.df-frow textarea { width: 100%; box-sizing: border-box; padding: 7px 9px;
  background: var(--df-card); color: var(--df-fg);
  border: 1px solid var(--df-border); border-radius: 8px; font-size: 13px;
  font-family: inherit; }
.df-frow input:focus, .df-frow select:focus, .df-frow textarea:focus {
  outline: none; border-color: var(--df-accent, #0074D2); }
.df-frow input[type=checkbox] { width: 16px; height: 16px;
  accent-color: var(--df-accent, #0074D2); align-self: flex-start; }

/* key→value editor (e.g. adapter status_map) */
.df-kv { display: flex; flex-direction: column; gap: 6px; }
.df-kv-row { display: flex; gap: 6px; align-items: center; }
.df-kv-k { flex: 1; } .df-kv-v { flex: 1; }
.df-kv-rm { padding: 3px 8px; background: transparent; color: var(--df-muted);
  border: 1px solid var(--df-border); border-radius: 6px; cursor: pointer; }
.df-kv-add { align-self: flex-start; padding: 3px 10px; background: transparent;
  color: var(--df-muted); border: 1px dashed var(--df-border); border-radius: 6px;
  font-size: 11.5px; cursor: pointer; }

/* Actions */
.df-modal-actions { display: flex; align-items: center; gap: 8px; margin-top: 16px; }
.df-confirm-q { font-size: 12.5px; color: var(--df-red-t); }
.df-btn { padding: 7px 15px; background: var(--df-card); color: var(--df-fg);
  border: 1px solid var(--df-border); border-radius: 8px; font-size: 13px;
  font-weight: 600; cursor: pointer; }
.df-btn:hover { border-color: var(--df-muted); }
.df-btn:disabled { opacity: .5; cursor: default; }
.df-btn-primary { background: var(--df-accent, #0074D2); color: #fff;
  border-color: var(--df-accent, #0074D2); }
.df-btn-danger { background: transparent; color: var(--df-red-s);
  border-color: var(--df-red-s); }
.df-btn-danger:hover { background: var(--df-red-f); }

/* ════════════════════════════════════════════════════════════════════════
   RI-2026-138 Phase 3 (DCR-2026-890): interactive designer — node palette
   (df-edit-add chips, already styled above) + edge authoring. Drag a node onto
   another to connect; click a connection to remove.
   ════════════════════════════════════════════════════════════════════════ */
.df-node.df-connectable { cursor: crosshair; }
.df-node.df-connectable:hover rect.df-box { stroke-width: 2.5; filter: brightness(1.06); }
/* M4: while dragging a connection, valid drop-target nodes light up green so the
   operator sees where the connection can land. */
.df-node.df-drop-ok rect.df-box { stroke: var(--df-green-s); stroke-width: 2.5;
  stroke-dasharray: 5 3; filter: brightness(1.08); }
/* Authorable edges are deletable: a wider transparent hit path catches the click,
   and the visible line turns red on hover. */
.df-edge.df-edge-editable:hover { stroke: var(--df-red-s); stroke-width: 2.5; }
.df-edge-hit { cursor: pointer; }

/* ════════════════════════════════════════════════════════════════════════
   RI-2026-138 Phase 4: swim-lane drag authoring — lane drop zones + headings.
   Lane rects are inert (pointer-events:none) in steady state so node/edge
   hit-testing is exactly Phase-3; only while a chip drag is active (the scroll
   carries .df-dragging) do they intercept the pointer to detect the drop lane.
   ════════════════════════════════════════════════════════════════════════ */
.df-lane-zone { fill: transparent; pointer-events: none; transition: fill .12s; }
.df-scroll.df-dragging .df-lane-zone { pointer-events: all; }
.df-lane-zone.df-lane-drop-ok  { fill: var(--df-green-f, rgba(34,197,94,.10)); }
.df-lane-zone.df-lane-drop-bad { fill: var(--df-red-f, rgba(239,68,68,.08)); }
.df-lane-label { font-size: 10px; font-weight: 700; fill: var(--df-muted);
  text-anchor: middle; letter-spacing: .04em; text-transform: uppercase; }
