/* =========================================================================
   Kennisgraaf — standalone interactive knowledge graph
   Design language adapted from AP_microsite (editorial: paper/ink + accents,
   fluid type, self-hosted Ease display font, sharp corners, hairline rules).
   ========================================================================= */

/* ---- fonts (self-hosted, relative) ------------------------------------- */
@font-face { font-family:"Ease Display";    src:url("./fonts/EaseDisplay-Regular.woff2") format("woff2");     font-weight:400; font-style:normal; font-display:swap; }
@font-face { font-family:"Ease SemiDisplay"; src:url("./fonts/EaseSemiDisplay-Semibold.woff2") format("woff2"); font-weight:600; font-style:normal; font-display:swap; }
@font-face { font-family:"Ease SemiDisplay"; src:url("./fonts/EaseSemiDisplay-Black.woff2") format("woff2");    font-weight:900; font-style:normal; font-display:swap; }
@font-face { font-family:"DM Sans"; src:url("./fonts/DMSans-Regular.woff2") format("woff2");  font-weight:400; font-style:normal; font-display:swap; }
@font-face { font-family:"DM Sans"; src:url("./fonts/DMSans-SemiBold.woff2") format("woff2"); font-weight:600; font-style:normal; font-display:swap; }
@font-face { font-family:"DM Sans"; src:url("./fonts/DMSans-Bold.woff2") format("woff2");     font-weight:700 900; font-style:normal; font-display:swap; }

/* ---- tokens ------------------------------------------------------------ */
:root {
  --paper:#fafaf7; --ink:#14171a; --muted:#6b7178; --line:#e6e4dd;
  --surface:#ffffff;                 /* raised frosted panels */
  --surface-2:#f4f2ec;

  /* six brand accents */
  --c-teal:#2bebcb; --c-pink:#ff9bfc; --c-gold:#e5c574;
  --c-yellow:#fff347; --c-green:#58eb81; --c-purple:#a187ff;

  /* node-type colours (the primary encoding; read by app.js via getComputedStyle) */
  --node-domain:#17b9a0;     /* teal, darkened for contrast on paper */
  --node-practice:#7b61ff;   /* purple */
  --node-bron:#c99a2e;       /* gold, darkened */
  --node-begrip:#e46fd6;     /* pink, darkened */
  --node-phase:#2fb457;      /* green */
  --node-level:#c9a400;      /* yellow, darkened */
  --node-categorie:#8b9099;  /* grey */

  --font-display:"Ease SemiDisplay","DM Sans",system-ui,sans-serif;
  --font-body:"Ease Display","DM Sans",system-ui,sans-serif;

  --step--1:clamp(.78rem,.74rem + .18vw,.86rem);
  --step-0: clamp(.94rem,.9rem + .2vw,1.02rem);
  --step-1: clamp(1.15rem,1.05rem + .5vw,1.45rem);
  --step-2: clamp(1.5rem,1.25rem + 1.2vw,2.3rem);
  --step-3: clamp(2rem,1.5rem + 2.4vw,3.2rem);

  --space-1:.5rem; --space-2:1rem; --space-3:1.5rem; --space-4:2.5rem;
  --radius:0; --radius-card:2px; --pill:999px;
  --rail-w:19rem; --panel-w:27rem;

  --shadow-panel:0 18px 50px -28px rgba(20,23,26,.55);
  --shadow-float:0 8px 26px -18px rgba(20,23,26,.5);
  color-scheme:light;
}

:root[data-theme="dark"] {
  --paper:#111113; --ink:#f3f3f1; --muted:#9a9b9d; --line:#2c2c31;
  --surface:#1a1a1d; --surface-2:#232327;

  /* keep hue in dark mode (colour == node type) — lifted for contrast on dark paper */
  --node-domain:#3fe6cb; --node-practice:#a794ff; --node-bron:#e5c574;
  --node-begrip:#ff9bfc; --node-phase:#5fe088; --node-level:#f4e04d;
  --node-categorie:#9aa0aa;

  --shadow-panel:0 18px 50px -20px rgba(0,0,0,.7);
  --shadow-float:0 10px 30px -14px rgba(0,0,0,.6);
  color-scheme:dark;
}

/* ---- reset ------------------------------------------------------------- */
*,*::before,*::after { box-sizing:border-box; }
html,body { height:100%; }
body {
  margin:0; overflow:hidden;
  background:var(--paper); color:var(--ink);
  font-family:var(--font-body); font-size:var(--step-0); line-height:1.5;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}
button { font:inherit; color:inherit; cursor:pointer; background:none; border:none; }
:focus-visible { outline:2.5px solid var(--node-practice); outline-offset:2px; }
::-webkit-scrollbar { width:10px; height:10px; }
::-webkit-scrollbar-thumb { background:color-mix(in srgb,var(--muted) 40%,transparent); border-radius:99px; border:2px solid transparent; background-clip:padding-box; }
::-webkit-scrollbar-track { background:transparent; }

.eyebrow {
  font-family:var(--font-display); font-weight:600; font-size:var(--step--1);
  text-transform:uppercase; letter-spacing:.14em; color:var(--muted);
}

/* ---- app shell --------------------------------------------------------- */
#app { display:grid; grid-template-rows:auto 1fr; height:100vh; height:100dvh; }

/* ---- top bar ----------------------------------------------------------- */
.topbar {
  display:flex; align-items:center; gap:var(--space-3);
  padding:.7rem clamp(1rem,2vw,1.6rem);
  border-bottom:1px solid var(--line);
  background:color-mix(in srgb,var(--paper) 86%,transparent);
  backdrop-filter:saturate(1.2) blur(10px);
  -webkit-backdrop-filter:saturate(1.2) blur(10px);
  z-index:20;
}
.brand { display:flex; flex-direction:column; gap:.1rem; min-width:0; }
.brand h1 {
  margin:0; font-family:var(--font-display); font-weight:900;
  font-size:var(--step-2); line-height:1; letter-spacing:-.02em;
}
.brand .sub { color:var(--muted); font-size:var(--step--1); white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; }
.brand .sub b { color:var(--ink); font-weight:600; font-variant-numeric:tabular-nums; }

.topbar-spacer { flex:1 1 auto; }
.topbar-tools { display:flex; align-items:center; gap:.6rem; }

/* search */
.search { position:relative; }
.search input {
  width:min(46vw,20rem); padding:.5rem .8rem .5rem 2rem;
  background:var(--surface); color:var(--ink);
  border:1px solid var(--line); border-radius:var(--pill);
  font-family:var(--font-body); font-size:var(--step-0);
  transition:border-color .15s, box-shadow .15s;
}
.search input:focus { border-color:var(--node-practice); box-shadow:0 0 0 3px color-mix(in srgb,var(--node-practice) 22%,transparent); outline:none; }
.search .ic { position:absolute; left:.6rem; top:50%; transform:translateY(-50%); color:var(--muted); pointer-events:none; }
.search-results {
  position:absolute; top:calc(100% + .4rem); left:0; right:0; z-index:40;
  max-height:min(50vh,22rem); overflow:auto;
  background:var(--surface); border:1px solid var(--line);
  box-shadow:var(--shadow-panel); display:none;
}
.search-results.open { display:block; }
.search-results button {
  display:flex; align-items:center; gap:.5rem; width:100%; text-align:left;
  padding:.5rem .7rem; border-bottom:1px solid var(--line); font-size:var(--step--1);
}
.search-results button:last-child { border-bottom:none; }
.search-results button:hover, .search-results button.active { background:var(--surface-2); }
.search-results .type-tag { margin-left:auto; }
.search-empty { padding:.7rem; color:var(--muted); font-size:var(--step--1); }

/* icon buttons in topbar */
.iconbtn {
  display:inline-grid; place-items:center; width:2.3rem; height:2.3rem;
  border:1px solid var(--line); border-radius:var(--pill);
  background:var(--surface); color:var(--ink); transition:background .15s,border-color .15s,transform .1s;
}
.iconbtn:hover { background:var(--surface-2); border-color:var(--muted); }
.iconbtn:active { transform:scale(.94); }
.iconbtn .moon { display:none; }
:root[data-theme="dark"] .iconbtn .sun { display:none; }
:root[data-theme="dark"] .iconbtn .moon { display:block; }

.filters-toggle { display:none; }

.switchlink {
  display:inline-flex; align-items:center; gap:.4rem; white-space:nowrap;
  padding:.5rem .9rem; border:1px solid var(--line); border-radius:var(--pill);
  background:var(--surface); color:var(--ink); text-decoration:none;
  font-family:var(--font-display); font-weight:600; font-size:var(--step--1);
  transition:border-color .15s, background .15s, transform .1s;
}
.switchlink:hover { background:var(--surface-2); border-color:var(--muted); }
.switchlink:active { transform:scale(.97); }

/* ---- stage (graph + floating panels) ----------------------------------- */
.stage { position:relative; overflow:hidden; }
#graph { position:absolute; inset:0; }
#graph canvas { display:block; }

.loading {
  position:absolute; inset:0; display:grid; place-items:center; z-index:5;
  color:var(--muted); font-family:var(--font-display); letter-spacing:.04em;
  transition:opacity .4s; pointer-events:none;
}
.loading.hidden { opacity:0; }
.loading .dot { display:inline-block; width:.5rem; height:.5rem; border-radius:99px;
  background:var(--node-practice); margin:0 .15rem; animation:pulse 1.1s infinite ease-in-out; }
.loading .dot:nth-child(2){ animation-delay:.15s; } .loading .dot:nth-child(3){ animation-delay:.3s; }
@keyframes pulse { 0%,80%,100%{ opacity:.25; transform:scale(.8);} 40%{ opacity:1; transform:scale(1);} }

/* ---- rail (filters + legend) ------------------------------------------ */
.rail {
  position:absolute; top:1rem; left:1rem; z-index:15;
  width:var(--rail-w); max-height:calc(100% - 2rem); overflow:auto;
  padding:1.1rem 1.1rem 1.3rem;
  background:color-mix(in srgb,var(--surface) 90%,transparent);
  backdrop-filter:saturate(1.15) blur(10px); -webkit-backdrop-filter:saturate(1.15) blur(10px);
  border:1px solid var(--line); box-shadow:var(--shadow-float);
}
.rail h2 {
  margin:0 0 .5rem; font-family:var(--font-display); font-weight:600;
  font-size:var(--step--1); text-transform:uppercase; letter-spacing:.1em; color:var(--muted);
}
.rail .group + .group { margin-top:1.2rem; }
.rail .group-head { display:flex; align-items:baseline; justify-content:space-between; }
.rail .reset {
  font-size:var(--step--1); color:var(--muted); text-decoration:underline;
  text-underline-offset:3px; text-transform:none; letter-spacing:0; font-family:var(--font-body);
}
.rail .reset:hover { color:var(--ink); }

/* type filter rows (legend + toggle in one) */
.legend { display:flex; flex-direction:column; gap:.15rem; }
.legrow {
  display:flex; align-items:center; gap:.6rem; width:100%; text-align:left;
  padding:.4rem .5rem; border-radius:var(--radius-card); transition:background .12s;
}
.legrow:hover { background:var(--surface-2); }
.legrow .swatch { width:.85rem; height:.85rem; border-radius:99px; flex:none; box-shadow:0 0 0 3px color-mix(in srgb,var(--sw) 20%,transparent); background:var(--sw); }
.legrow .lbl { font-size:var(--step-0); }
.legrow .cnt { margin-left:auto; color:var(--muted); font-size:var(--step--1); font-variant-numeric:tabular-nums; }
.legrow.off { opacity:.4; }
.legrow.off .swatch { background:var(--muted); box-shadow:none; }

/* pill chips for secondary filters (phases / levels / categories) */
.chips { display:flex; flex-wrap:wrap; gap:.4rem; }
.chip {
  padding:.28rem .7rem; border:1px solid var(--line); border-radius:var(--pill);
  font-size:var(--step--1); color:var(--muted); background:var(--surface);
  transition:all .12s; white-space:nowrap;
}
.chip:hover { border-color:var(--muted); color:var(--ink); }
.chip.on { background:var(--ink); color:var(--paper); border-color:var(--ink); }
.subhint { color:var(--muted); font-size:var(--step--1); margin:.15rem 0 .5rem; }

/* ---- zoom controls ----------------------------------------------------- */
.controls { position:absolute; left:1rem; bottom:1rem; z-index:15; display:flex; flex-direction:column; gap:.4rem; }
.controls button {
  width:2.4rem; height:2.4rem; display:grid; place-items:center;
  background:color-mix(in srgb,var(--surface) 92%,transparent);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  border:1px solid var(--line); box-shadow:var(--shadow-float);
  font-size:1.1rem; line-height:1; transition:background .12s,transform .1s;
}
.controls button:hover { background:var(--surface-2); }
.controls button:active { transform:scale(.92); }

.hint {
  position:absolute; right:1rem; bottom:1rem; z-index:12;
  color:var(--muted); font-size:var(--step--1); pointer-events:none;
  background:color-mix(in srgb,var(--paper) 60%,transparent); padding:.2rem .5rem;
  transition:opacity .3s;
}

/* ---- detail panel ------------------------------------------------------ */
.panel {
  position:absolute; top:0; right:0; z-index:18;
  width:min(var(--panel-w),92vw); height:100%;
  background:color-mix(in srgb,var(--surface) 94%,transparent);
  backdrop-filter:saturate(1.15) blur(12px); -webkit-backdrop-filter:saturate(1.15) blur(12px);
  border-left:1px solid var(--line); box-shadow:var(--shadow-panel);
  transform:translateX(100%); transition:transform .32s cubic-bezier(.2,.7,.2,1);
  display:flex; flex-direction:column;
}
.panel.open { transform:translateX(0); }
.panel-head {
  padding:1.1rem 1.2rem .9rem; border-bottom:1px solid var(--line);
  display:flex; align-items:flex-start; gap:.6rem;
}
.panel-head .grow { min-width:0; }
.type-tag {
  display:inline-flex; align-items:center; gap:.4rem;
  font-family:var(--font-display); font-weight:600; font-size:.72rem;
  text-transform:uppercase; letter-spacing:.08em;
  padding:.2rem .55rem; border-radius:var(--pill);
  color:var(--tt-ink,var(--ink)); background:color-mix(in srgb,var(--tt,var(--muted)) 16%,transparent);
}
.type-tag .dot { width:.5rem; height:.5rem; border-radius:99px; background:var(--tt,var(--muted)); }
.panel h2 {
  margin:.55rem 0 0; font-family:var(--font-display); font-weight:900;
  font-size:var(--step-1); line-height:1.1; letter-spacing:-.01em;
}
.panel .close {
  flex:none; width:2rem; height:2rem; display:grid; place-items:center;
  border:1px solid var(--line); border-radius:var(--pill); color:var(--muted);
}
.panel .close:hover { color:var(--ink); background:var(--surface-2); }

.panel-body { padding:1rem 1.2rem 2rem; overflow:auto; flex:1 1 auto; }
.panel-body h3 {
  margin:1.3rem 0 .5rem; font-family:var(--font-display); font-weight:600;
  font-size:var(--step--1); text-transform:uppercase; letter-spacing:.1em; color:var(--muted);
}
.panel-body h3:first-child { margin-top:.2rem; }
.panel-body p { margin:.5rem 0; }
.panel-body .lede { font-size:var(--step-1); line-height:1.45; color:var(--ink); }
.prose p { color:color-mix(in srgb,var(--ink) 88%,var(--muted)); }
.prose ul { margin:.4rem 0 .4rem 1.1rem; padding:0; }
.prose li { margin:.25rem 0; }
.prose strong { font-weight:600; }
.prose table { border-collapse:collapse; width:100%; font-size:var(--step--1); margin:.5rem 0; }
.prose th, .prose td { border:1px solid var(--line); padding:.3rem .5rem; text-align:left; vertical-align:top; }
.prose th { background:var(--surface-2); font-weight:600; }

/* relation chips inside panel */
.rel { display:flex; flex-wrap:wrap; gap:.4rem; }
.rel button {
  display:inline-flex; align-items:center; gap:.4rem; max-width:100%;
  padding:.3rem .6rem; border:1px solid var(--line); border-radius:var(--pill);
  font-size:var(--step--1); background:var(--surface); transition:all .12s;
}
.rel button:hover { border-color:var(--rc,var(--muted)); background:var(--surface-2); }
.rel button .dot { width:.5rem; height:.5rem; border-radius:99px; background:var(--rc,var(--muted)); flex:none; }
.rel button .t { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

.openpage {
  display:inline-flex; align-items:center; gap:.5rem; margin-top:1.4rem;
  padding:.6rem 1rem; background:var(--ink); color:var(--paper);
  font-family:var(--font-display); font-weight:600; font-size:var(--step-0);
  border-radius:var(--pill); transition:transform .1s, opacity .15s; text-decoration:none;
}
.openpage:hover { transform:translateY(-1px); opacity:.92; }
.meta-line { color:var(--muted); font-size:var(--step--1); margin-top:.3rem; }
.meta-line a { color:var(--node-practice); text-decoration:none; word-break:break-all; }
.meta-line a:hover { text-decoration:underline; }

/* hover tooltip over canvas */
.gtip {
  position:absolute; z-index:30; pointer-events:none; display:none;
  padding:.35rem .6rem; background:var(--ink); color:var(--paper);
  font-size:var(--step--1); border-radius:2px; box-shadow:var(--shadow-float);
  max-width:16rem; transform:translate(-50%,calc(-100% - 10px));
}
.gtip .tt-type { color:color-mix(in srgb,var(--paper) 65%,transparent); font-size:.7rem;
  text-transform:uppercase; letter-spacing:.08em; }

/* ---- responsive -------------------------------------------------------- */
@media (max-width:820px) {
  .brand .sub { display:none; }
  .filters-toggle { display:inline-grid; }
  .rail {
    inset:auto 1rem 1rem 1rem; top:1rem; width:auto; max-height:70%;
    transform:translateY(0); transition:transform .3s, opacity .3s;
  }
  .rail.collapsed { transform:translateY(12px); opacity:0; pointer-events:none; }
  .search input { width:min(60vw,16rem); }
  .panel { width:100%; }
  .hint { display:none; }
}
@media (max-width:520px) {
  .search input { width:44vw; }
  .brand h1 { font-size:var(--step-1); }
}

/* ---- reduced motion ---------------------------------------------------- */
@media (prefers-reduced-motion:reduce) {
  * { animation-duration:.001ms !important; transition-duration:.001ms !important; }
}
