/* The Modern Stack — zoomable universe.
   Palette: dataviz reference instance, dark steps (validator: all checks pass). */

:root{
  --surface-0:#111110;
  --surface-1:#1a1a19;
  --surface-2:#232321;
  --surface-3:#2d2d2a;
  --line:#3a3a36;
  --text-1:#ffffff;
  --text-2:#c3c2b7;
  --text-3:#8a8980;

  --t1:#3987e5; --t2:#d95926; --t3:#199e70; --t4:#c98500;
  --t5:#d55181; --t6:#008300; --t7:#9085e9; --t8:#e66767;

  --bar-h:60px; --legend-h:44px;
  --ui:ui-sans-serif,-apple-system,"Segoe UI",Inter,system-ui,sans-serif;
  --mono:ui-monospace,"SF Mono","Cascadia Mono",Menlo,Consolas,monospace;
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;background:var(--surface-0);color:var(--text-1);
  font-family:var(--ui);-webkit-font-smoothing:antialiased;
  overflow:hidden;
}

/* top bar */
.bar{
  position:fixed;inset:0 0 auto 0;height:var(--bar-h);z-index:40;
  display:flex;align-items:center;justify-content:space-between;gap:24px;
  padding:0 16px;background:rgba(17,17,16,.86);backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line);
}
.brand{display:flex;align-items:center;gap:12px;min-width:0}
.brand .mark{
  width:26px;height:26px;border-radius:7px;flex:none;
  background:
    radial-gradient(circle at 30% 30%,var(--t1) 0 22%,transparent 23%),
    radial-gradient(circle at 72% 34%,var(--t2) 0 18%,transparent 19%),
    radial-gradient(circle at 34% 72%,var(--t3) 0 18%,transparent 19%),
    radial-gradient(circle at 70% 70%,var(--t7) 0 22%,transparent 23%),
    var(--surface-2);
  border:1px solid var(--line);
}
.brand h1{font-size:14px;margin:0;letter-spacing:.14em;text-transform:uppercase}
.brand p{margin:1px 0 0;font-size:11px;color:var(--text-3);font-family:var(--mono)}

.tools{display:flex;align-items:center;gap:10px}
.search{
  display:flex;align-items:center;gap:8px;height:34px;padding:0 10px;
  background:var(--surface-2);border:1px solid var(--line);border-radius:8px;
  transition:border-color .15s;
}
.search:focus-within{border-color:var(--t1)}
.search svg{width:15px;height:15px;fill:none;stroke:var(--text-3);stroke-width:1.8;stroke-linecap:round}
.search input{
  width:230px;background:none;border:0;outline:0;color:var(--text-1);
  font:13px/1 var(--ui);
}
.search input::placeholder{color:var(--text-3)}
.search button{background:none;border:0;color:var(--text-3);font-size:17px;cursor:pointer;line-height:1}

.zoom{display:flex;background:var(--surface-2);border:1px solid var(--line);border-radius:8px;overflow:hidden}
.zoom button{
  height:32px;min-width:34px;padding:0 8px;background:none;border:0;cursor:pointer;
  color:var(--text-2);font:12px/1 var(--mono);
}
.zoom button:hover{background:var(--surface-3);color:var(--text-1)}
#zlevel{min-width:56px;border-left:1px solid var(--line);border-right:1px solid var(--line)}

.toggle{
  height:34px;padding:0 12px;border-radius:8px;cursor:pointer;
  background:var(--surface-2);border:1px solid var(--line);color:var(--text-2);
  font:12px/1 var(--ui);letter-spacing:.04em;
}
.toggle:hover{color:var(--text-1)}
.toggle[aria-pressed="true"]{background:var(--t1);border-color:var(--t1);color:#fff}

/* tier legend */
.legend{
  position:fixed;top:var(--bar-h);left:0;right:0;height:var(--legend-h);z-index:39;
  display:flex;align-items:center;gap:6px;padding:0 16px;overflow-x:auto;
  background:rgba(17,17,16,.8);backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line);scrollbar-width:none;
}
.legend::-webkit-scrollbar{display:none}
.legend button{
  display:flex;align-items:center;gap:7px;flex:none;height:26px;padding:0 11px;
  background:var(--surface-2);border:1px solid var(--line);border-radius:99px;
  color:var(--text-2);font:11.5px/1 var(--ui);cursor:pointer;white-space:nowrap;
  letter-spacing:.03em;
}
.legend button:hover{color:var(--text-1);border-color:var(--text-3)}
.legend button i{width:8px;height:8px;border-radius:99px;background:var(--c);flex:none}
.legend button b{font-weight:500;font-family:var(--mono);font-size:10px;color:var(--text-3)}

/* stage / world */
.stage{
  position:fixed;inset:calc(var(--bar-h) + var(--legend-h)) 0 0 0;
  overflow:hidden;cursor:grab;touch-action:none;
  -webkit-user-select:none;user-select:none;   /* a pan drag must never select label text */
  background:
    radial-gradient(1200px 700px at 20% 0%,#191a22 0%,transparent 60%),
    radial-gradient(900px 600px at 85% 100%,#1c1918 0%,transparent 60%),
    var(--surface-0);
}
.stage.dragging{cursor:grabbing}
.world{position:absolute;top:0;left:0;transform-origin:0 0;will-change:transform}

/* ── the scene ────────────────────────────────────────────
   Everything lives in one SVG in world coordinates: tier haloes,
   edges, then nodes on top. The svg itself is transparent to the
   pointer so a drag anywhere pans; only nodes take the pointer. */
.scene{position:absolute;top:0;left:0;overflow:visible;pointer-events:none}

/* tier + layer haloes */
.thalo{fill:var(--c);fill-opacity:.055;stroke:var(--c);stroke-opacity:.34;stroke-width:calc(1.5px / var(--k))}
.lhalo{fill:#ffffff;fill-opacity:.018;stroke:var(--c);stroke-opacity:.2;stroke-width:calc(1px / var(--k));stroke-dasharray:calc(5px / var(--k)) calc(5px / var(--k))}
.tname{
  fill:var(--c);text-anchor:middle;font-family:var(--ui);font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;
  font-size:min(calc(27px / var(--k)),133px);
}
.tnote{fill:var(--text-3);text-anchor:middle;font-family:var(--ui);font-size:min(calc(19.8px / var(--k)),72px)}
.lname{
  fill:var(--text-1);text-anchor:middle;font-family:var(--ui);font-weight:600;
  font-size:min(calc(20.7px / var(--k)),38px);letter-spacing:.02em;
}
/* the layer name rides a pill at the centre of its disc, not floating above it */
.lpill{fill:var(--surface-0);fill-opacity:.9;stroke:var(--c);stroke-opacity:.5;
  stroke-width:calc(1.4px / var(--k))}
.lpillg{pointer-events:none}
.lcount{fill:var(--text-3);text-anchor:middle;font-family:var(--mono);font-size:min(calc(16.2px / var(--k)),26px)}

/* edges — always drawn, never a toggle you have to find */
.edge{fill:none;stroke:#7d7c73;stroke-opacity:.16;stroke-width:calc(1.1px / var(--k));stroke-linecap:round}
.edge.cross{stroke-opacity:.24}
#gedge.all .edge{stroke-opacity:.42}
.edge.hot{stroke:var(--ec);stroke-opacity:.95;stroke-width:calc(2.4px / var(--k))}

/* nodes */
.node{pointer-events:auto;cursor:pointer}
.node circle{
  fill:var(--c);fill-opacity:.9;stroke:var(--surface-0);stroke-width:calc(1.5px / var(--k));
  transition:fill-opacity .12s;
}
.node .lb{
  fill:var(--text-2);text-anchor:middle;font-family:var(--ui);font-weight:500;
  font-size:min(calc(19.8px / var(--k)),31px);pointer-events:none;
  paint-order:stroke;stroke:var(--surface-0);stroke-width:calc(5px / var(--k));stroke-linejoin:round;
}
.node .ring{fill:none;stroke:var(--c);stroke-width:calc(2px / var(--k));opacity:0}
.node:hover circle,.node.hot circle{fill-opacity:1}
.node.hot .ring,.node.lit .ring{opacity:1}
.node.pin .ring{opacity:1;stroke-width:calc(3.4px / var(--k))}
.node.hot .lb,.node.lit .lb{fill:var(--text-1)}

/* neighbourhood focus: everything not in the hovered node's orbit recedes */
#gnode.lit .node{opacity:.16}
#gnode.lit .node.hot,#gnode.lit .node.lit{opacity:1}
#gnode.lit .node.pin .lb{display:block;fill:var(--text-1)}
#ghalo.lit{opacity:.4}
#gpill.lit{opacity:.35}

/* Semantic zoom — pulled back, the tool labels would be 3px tall, so the
   tier and layer names carry the map instead and grow in inverse-scale units. */
.world.z-far .node .lb{display:none}
.world.z-mid .node .lb{display:none}
.world.z-mid .node.hub .lb{display:block}
.world.z-far .lname,.world.z-far .lcount,.world.z-far .lpill{display:none}
/* the tier subtitle reads at every zoom, near included */

/* search */
#gnode.filtering .node{opacity:.1}
#gnode.filtering .node.hit{opacity:1}
#gnode.filtering .node.hit .ring{opacity:1}
#gnode.filtering .node.hit .lb{display:block;fill:var(--text-1)}
#gedge.filtering .edge{stroke-opacity:.05}
.lhalo.lhit{fill-opacity:.06;stroke-opacity:.85;stroke-dasharray:none}
.lpill.lhit{fill-opacity:.97;stroke-opacity:1;stroke-width:calc(2px / var(--k))}
.lname.lhit{fill:var(--text-1)}

/* hover card */
/* the hover card carries the whole record -- there is no second dialog to open */
.tip{
  position:absolute;z-index:30;width:330px;max-width:330px;padding:11px 13px 12px;
  border-radius:10px;background:rgba(26,26,25,.97);border:1px solid var(--line);
  border-left:3px solid var(--c,var(--t1));
  box-shadow:0 16px 40px rgba(0,0,0,.55);pointer-events:none;
}
.tip.pinned{pointer-events:auto;border-color:var(--c,var(--t1));box-shadow:0 18px 46px rgba(0,0,0,.65)}
.tip[hidden]{display:none}
.tip .crumb{display:block;font:9.5px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--c,var(--t1))}
.tip b{display:block;margin-top:5px;font:600 14.5px/1.2 var(--ui);color:var(--text-1)}
.tip .meta{display:block;margin-top:4px;font:9.5px/1 var(--mono);letter-spacing:.09em;text-transform:uppercase;color:var(--text-3)}
.tip .bl{display:block;margin-top:7px;font:12.5px/1.4 var(--ui);color:var(--text-2)}
.tip .sec{display:block;margin-top:8px}
.tip .sec[hidden]{display:none}
.tip .sec i{display:block;font:600 9.5px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-3);font-style:normal}
.tip .sec em{display:block;margin-top:3px;font:12px/1.4 var(--ui);font-style:normal;color:var(--text-2)}
#tip-rl{color:var(--text-3);font-size:11.5px}
.tip .out{display:none}
.tip.pinned .out{display:inline-block;margin-top:9px;font:600 11.5px/1 var(--ui);
  color:var(--c,var(--t1));text-decoration:none}
.tip.pinned .out:hover{text-decoration:underline}
.tip .cta{display:block;margin-top:9px;font:11px/1 var(--ui);color:var(--text-3)}

/* hint + minimap */
.hint{
  position:absolute;left:16px;bottom:16px;z-index:20;
  padding:7px 12px;border-radius:8px;background:rgba(26,26,25,.9);
  border:1px solid var(--line);color:var(--text-3);font:11.5px/1 var(--ui);
  transition:opacity .5s;
}
.hint b{color:var(--text-2);font-weight:600}
.hint.gone{opacity:0}

.minimap{
  position:absolute;right:16px;bottom:16px;z-index:20;width:200px;height:200px;
  border-radius:10px;border:1px solid var(--line);background:rgba(17,17,16,.9);
  overflow:hidden;cursor:crosshair;
}
.minimap canvas{display:block;width:200px;height:200px}
.mmview{position:absolute;border:1.5px solid var(--text-1);border-radius:3px;pointer-events:none;background:rgba(255,255,255,.07)}

/* modal */
.modal{
  position:fixed;inset:0;z-index:60;display:grid;place-items:center;padding:24px;
  background:rgba(8,8,8,.72);backdrop-filter:blur(4px);
}
.modal[hidden]{display:none}
.sheet{-webkit-user-select:text;user-select:text;
  position:relative;width:min(620px,100%);max-height:86vh;overflow:auto;
  background:var(--surface-1);border:1px solid var(--line);border-top:3px solid var(--c,var(--t1));
  border-radius:14px;padding:26px 28px 28px;
  box-shadow:0 30px 80px rgba(0,0,0,.6);
}
.sheet .x{
  position:absolute;right:14px;top:12px;width:28px;height:28px;border-radius:7px;
  background:var(--surface-2);border:1px solid var(--line);color:var(--text-2);
  font-size:17px;line-height:1;cursor:pointer;
}
.sheet .x:hover{background:var(--surface-3);color:var(--text-1)}
.crumb{margin:0;font:11px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--c,var(--t1))}
.sheet h2{margin:9px 0 0;font:600 27px/1.15 var(--ui);letter-spacing:-.01em}
.tagline{margin:8px 0 0;font:15px/1.5 var(--ui);color:var(--text-2)}
.badges{display:flex;flex-wrap:wrap;gap:6px;margin-top:14px}
.badges span{
  padding:4px 9px;border-radius:99px;background:var(--surface-2);border:1px solid var(--line);
  font:10.5px/1 var(--mono);color:var(--text-2);letter-spacing:.06em;text-transform:uppercase;
}
.sheet section{margin-top:22px}
.sheet h3{
  margin:0 0 7px;font:600 11px/1 var(--ui);letter-spacing:.14em;text-transform:uppercase;color:var(--text-3);
}
.sheet section p{margin:0;font:14px/1.62 var(--ui);color:var(--text-2)}
.rel{display:flex;flex-wrap:wrap;gap:7px}
.rel button{
  display:flex;align-items:center;gap:7px;padding:6px 11px;border-radius:99px;cursor:pointer;
  background:var(--surface-2);border:1px solid var(--line);color:var(--text-2);font:12px/1 var(--ui);
}
.rel button:hover{color:var(--text-1);border-color:var(--text-3)}
.rel button i{width:7px;height:7px;border-radius:99px;background:var(--rc);flex:none}
.out{
  display:inline-block;margin-top:22px;padding:9px 15px;border-radius:8px;
  background:var(--surface-2);border:1px solid var(--line);color:var(--text-1);
  font:12.5px/1 var(--ui);text-decoration:none;
}
.out:hover{border-color:var(--text-3);background:var(--surface-3)}

@media (max-width:760px){
  .search input{width:120px}
  .minimap{display:none}
  .brand p{display:none}
}
