/* ai_mesh.css — shared "AI Composer" scenario-mesh renderer.
   Layered SVG graph used by the AI-Driven modes (mesh planning, new-CTF wizard,
   challenge library). Themed through the app's existing tokens; the AI signature
   is violet. No external deps, CSP-safe. See ai_mesh.js. */

.aim-root{ --aim:#a78bfa; --aim-soft:rgba(167,139,250,.18);
  --aim-chal:#c4b5fd; --aim-svc:#fb923c; --aim-art:#22d3ee; --aim-obj:#34e39b;
  --aim-plan:#8aa697; --aim-gen:#fbbf24; --aim-live:#34e39b;
  position:relative; width:100%; }

/* The graph is a dark console on EVERY app theme (light or dark). The stage pins
   its own dark neutrals, so the SVG and the inspector inside it stay dark even on
   the light theme. The legend sits BELOW the stage (a sibling), so it keeps the
   page's own tokens and stays readable on a light page. */
.aim-stage{ position:relative; border:1px solid rgba(150,140,210,.18); border-radius:14px; overflow:hidden;
  --fg:#eaf5ee; --muted:#8aa697; --panel:#0a0f0c; --panel-soft:#0d1411; --line:rgba(150,140,210,.18);
  background:radial-gradient(1000px 460px at 13% 40%, var(--aim-soft), transparent 60%),
             linear-gradient(180deg,#0b1210,#070b09); }
.aim-stage::before{ content:""; position:absolute; inset:0; pointer-events:none;
  background-image:radial-gradient(rgba(167,139,250,.08) 1px,transparent 1px); background-size:26px 26px;
  mask-image:radial-gradient(circle at center,#000 62%,transparent 96%); }
.aim-svg{ display:block; width:100%; height:auto; }

/* edges */
.aim-edge{ fill:none; stroke:color-mix(in srgb,var(--aim) 52%,transparent); stroke-width:1.6; stroke-linecap:round;
  stroke-dasharray:var(--len); stroke-dashoffset:var(--len); transition:stroke-dashoffset .7s ease; }
.aim-edge.seed{ stroke:color-mix(in srgb,var(--aim) 72%,transparent); }
.aim-edge.svc{ stroke:color-mix(in srgb,var(--aim-svc) 42%,transparent); stroke-dasharray:3 6; stroke-width:1.3; }
.aim-svg.drawn .aim-edge{ stroke-dashoffset:0; }

/* nodes */
.aim-node{ opacity:0; transform:scale(.62); transform-box:fill-box; transform-origin:center; cursor:pointer;
  transition:opacity .4s ease, transform .4s cubic-bezier(.2,1.3,.4,1); }
.aim-node.shown{ opacity:1; transform:scale(1); }
.aim-body{ stroke-width:1.7; filter:drop-shadow(0 2px 6px rgba(0,0,0,.5)); }
.aim-node[data-role="challenge"] .aim-body{ fill:color-mix(in srgb,var(--aim-chal) 26%,var(--panel-soft,#0b120f)); stroke:color-mix(in srgb,var(--aim-chal) 88%,transparent); }
.aim-node[data-role="service"]   .aim-body{ fill:color-mix(in srgb,var(--aim-svc) 24%,var(--panel-soft,#0b120f)); stroke:color-mix(in srgb,var(--aim-svc) 82%,transparent); }
.aim-node[data-role="artifact"]  .aim-body{ fill:color-mix(in srgb,var(--aim-art) 22%,var(--panel-soft,#0b120f)); stroke:color-mix(in srgb,var(--aim-art) 82%,transparent); }
.aim-node[data-role="objective"] .aim-body{ fill:color-mix(in srgb,var(--aim-obj) 26%,var(--panel-soft,#0b120f)); stroke:var(--aim-obj); stroke-width:2.1; }
.aim-node.sel .aim-body{ stroke-width:2.5; filter:drop-shadow(0 0 7px color-mix(in srgb,var(--aim) 70%,transparent)); }
.aim-ico[data-role="challenge"]{ color:var(--aim-chal); } .aim-ico[data-role="service"]{ color:var(--aim-svc); }
.aim-ico[data-role="artifact"]{ color:var(--aim-art); } .aim-ico[data-role="objective"]{ color:var(--aim-obj); }
.aim-label{ font-weight:650; font-size:12.5px; fill:var(--fg,#f2fff6); }
.aim-sub{ font-family:ui-monospace,Menlo,Consolas,monospace; font-size:9px; letter-spacing:.03em; fill:var(--muted,#7f9c8a); }
.aim-node:hover .aim-body{ filter:brightness(1.16); }
.aim-node:focus-visible{ outline:none; }
.aim-node:focus-visible .aim-body{ stroke-width:2.5; filter:drop-shadow(0 0 6px var(--aim)); }

/* AI Composer core — PERMANENT animation (ring + scan arc + breathing disc). It
   never settles: the composer looks alive whenever the mesh is on screen. */
.aim-core-disc{ fill:var(--aim-soft); stroke:color-mix(in srgb,var(--aim) 72%,transparent); stroke-width:1.7;
  transform-box:fill-box; transform-origin:center; animation:aim-breathe 3.4s ease-in-out infinite; }
.aim-core-ring{ fill:none; stroke:color-mix(in srgb,var(--aim) 45%,transparent); stroke-width:1.4; stroke-dasharray:5 9;
  transform-box:fill-box; transform-origin:center; animation:aim-spin 9s linear infinite; }
.aim-core-scan{ fill:none; stroke:var(--aim); stroke-width:2.6; stroke-linecap:round; stroke-dasharray:40 210;
  transform-box:fill-box; transform-origin:center; animation:aim-spin 2.6s linear infinite; }
.aim-core-ico{ color:var(--aim); }
.aim-core-name{ font-family:ui-monospace,Menlo,Consolas,monospace; font-size:10px; font-weight:700; letter-spacing:.13em; fill:var(--aim); }
@keyframes aim-spin{ to{ transform:rotate(360deg); } }
@keyframes aim-breathe{ 0%,100%{ opacity:.7; } 50%{ opacity:1; } }

/* objective ambient pulse (the only motion in the calm resting state) */
.aim-obj-halo{ fill:none; stroke:var(--aim-obj); stroke-width:1.5; opacity:0; }
.aim-svg.calm .aim-obj-halo{ animation:aim-radiate 3s ease-out infinite; }
@keyframes aim-radiate{ 0%{ opacity:.5; r:30; } 70%{ opacity:0; } 100%{ opacity:0; r:52; } }

/* node inspector panel */
.aim-panel{ position:absolute; top:12px; right:12px; bottom:12px; width:266px; max-width:calc(100% - 24px); z-index:6;
  background:var(--panel,#070b09); border:1px solid color-mix(in srgb,var(--aim) 40%,var(--line,rgba(0,255,117,.3)));
  border-radius:13px; padding:15px; display:flex; flex-direction:column; gap:11px;
  transform:translateX(calc(100% + 22px)); transition:transform .3s cubic-bezier(.2,.9,.3,1);
  box-shadow:-8px 0 40px rgba(0,0,0,.45); }
.aim-panel.open{ transform:none; }
.aim-phd{ display:flex; align-items:flex-start; gap:10px; }
.aim-pico{ display:grid; place-items:center; width:34px; height:34px; border-radius:9px; flex:none; }
.aim-phd h4{ margin:0; font-size:.96rem; font-weight:750; line-height:1.2; color:var(--fg,#f2fff6); }
.aim-prole{ font-family:ui-monospace,Menlo,Consolas,monospace; font-size:.64rem; text-transform:uppercase; letter-spacing:.1em; color:var(--muted,#7f9c8a); }
.aim-pclose{ margin-left:auto; background:none; border:0; color:var(--muted,#7f9c8a); cursor:pointer; padding:2px; border-radius:6px; }
.aim-pclose:hover{ color:var(--fg,#f2fff6); }
.aim-prow{ display:flex; justify-content:space-between; align-items:center; gap:10px; font-size:.8rem; padding:7px 0; border-top:1px solid var(--line,rgba(0,255,117,.3)); }
.aim-prow .k{ color:var(--muted,#7f9c8a); } .aim-prow .v{ font-weight:650; color:var(--fg,#f2fff6); text-align:right; }
.aim-chip{ display:inline-flex; align-items:center; gap:6px; font-family:ui-monospace,Menlo,Consolas,monospace; font-size:.64rem; font-weight:700; letter-spacing:.05em; padding:3px 9px; border-radius:999px; border:1px solid currentColor; }
.aim-chip .d{ width:6px; height:6px; border-radius:50%; background:currentColor; }
.aim-chip.plan{ color:var(--aim-plan); } .aim-chip.gen{ color:var(--aim-gen); } .aim-chip.live{ color:var(--aim-live); }
.aim-desc-wrap{ display:flex; flex-direction:column; gap:5px; min-height:0; }
.aim-desc-label{ font-size:.62rem; text-transform:uppercase; letter-spacing:.1em; color:var(--muted,#7f9c8a); font-weight:600; }
.aim-desc{ font-size:.81rem; line-height:1.5; color:color-mix(in srgb,var(--fg,#f2fff6) 88%,transparent);
  overflow:auto; padding:9px 11px; border-radius:9px; background:var(--panel-soft,#0b120f);
  border:1px solid var(--line,rgba(0,255,117,.3)); white-space:pre-wrap; }
.aim-desc em{ color:var(--muted,#7f9c8a); font-style:normal; }
.aim-pfield label{ display:block; font-size:.62rem; text-transform:uppercase; letter-spacing:.1em; color:var(--muted,#7f9c8a); margin-bottom:5px; font-weight:600; }
.aim-pfield select{ width:100%; box-sizing:border-box; border:1px solid var(--line,rgba(0,255,117,.3)); background:var(--panel-soft,#0b120f); color:var(--fg,#f2fff6); border-radius:8px; padding:8px 10px; font:inherit; font-size:.82rem; }
.aim-pactions{ margin-top:auto; display:flex; gap:8px; }
.aim-btn{ flex:1; display:inline-flex; align-items:center; justify-content:center; gap:6px; font:inherit; font-size:.8rem; font-weight:650; cursor:pointer; border-radius:9px; padding:8px 12px; border:1px solid var(--line,rgba(0,255,117,.3)); background:var(--panel-soft,#0b120f); color:var(--fg,#f2fff6); }
.aim-btn:hover{ border-color:color-mix(in srgb,var(--aim) 55%,transparent); }
.aim-btn.primary{ background:color-mix(in srgb,var(--aim) 18%,transparent); border-color:color-mix(in srgb,var(--aim) 45%,transparent); }
.aim-btn:focus-visible{ outline:2px solid var(--aim); outline-offset:2px; }

/* legend + status strip */
.aim-legend{ display:flex; gap:12px; flex-wrap:wrap; font-size:.72rem; color:var(--muted,#7f9c8a); margin-top:11px; align-items:center; }
.aim-lg{ display:inline-flex; align-items:center; gap:6px; } .aim-lg span{ color:var(--fg,#f2fff6); }
/* Solid colour chips — must never read as empty checkboxes. Backgrounds are set
   per role explicitly (the generic `.aim-lg span` colour rule would otherwise
   win over currentColor and paint every swatch the text colour). */
.aim-lg .sw{ width:11px; height:11px; border-radius:3px; border:0; }
.aim-lg.ai   .sw{ background:var(--aim); }      .aim-lg.chal .sw{ background:var(--aim-chal); }
.aim-lg.svc  .sw{ background:var(--aim-svc); }  .aim-lg.art  .sw{ background:var(--aim-art); }
.aim-lg.obj  .sw{ background:var(--aim-obj); }
.aim-lg.stat .sw{ border-radius:50%; }
.aim-lg.plan .sw{ background:var(--aim-plan); } .aim-lg.gen .sw{ background:var(--aim-gen); } .aim-lg.live .sw{ background:var(--aim-live); }
.aim-lsep{ width:1px; height:15px; background:var(--line,rgba(0,255,117,.3)); }

@media (prefers-reduced-motion:reduce){
  .aim-edge{ transition:none; stroke-dashoffset:0; }
  .aim-node{ transition:none; opacity:1; transform:none; }
  .aim-core-ring,.aim-core-scan,.aim-core-disc,.aim-obj-halo{ animation:none !important; }
}
