/* ============================================================
   CONCEPT TIRAMISU — BREATHING ENERGY SYSTEM
   Layered DOM planes in CSS 3D + one SVG link overlay.
   No WebGL, no dependency. Loaded after v3.css.

   Weights driven from JS as custom properties on [data-esys]:
     --w-gen  --w-load  --w-store  --w-recover  --w-grid   (0..1)
     --cam-x  --cam-z   --cam-scale --cam-lift              (camera)
     --focus                                                (0 = none)
   ============================================================ */

/* ── stage ────────────────────────────────────────────────── */
.esys{
  --w-gen:.5; --w-load:.5; --w-store:.5; --w-recover:0; --w-grid:.5;
  --cam-x:21deg; --cam-z:-6deg; --cam-scale:1; --cam-lift:0px;
  --dim:1;
  position:relative; width:100%;
}
.esys__space{
  position:relative; width:100%; height:100%;
  perspective:1250px; perspective-origin:50% 46%; overflow:hidden;
}
.esys__world{
  position:absolute; inset:0;
  transform-style:preserve-3d;
  transform:translateY(var(--cam-lift)) scale(var(--cam-scale))
            rotateX(var(--cam-x)) rotateZ(var(--cam-z));
  transition:transform .9s cubic-bezier(.22,1,.28,1);
  will-change:transform;
}
.esys.is-scrubbing .esys__world{ transition:none; }

/* ── planes ───────────────────────────────────────────────── */
.esys__plane{
  position:absolute; left:9%; right:9%; height:0;
  top:calc(50% + var(--py));
  transform-style:preserve-3d;
  transform:translateZ(var(--pz));
  opacity:var(--po,1);
  transition:opacity .8s var(--ease);
}
/* a faint slab so the plane itself is perceivable */
.esys__plane::before{
  content:""; position:absolute; left:-3%; right:-3%; top:-34px; height:68px;
  border:1px solid rgba(196,129,26,.13); border-radius:3px; opacity:var(--dim);
  background:linear-gradient(90deg, rgba(196,129,26,.055), rgba(196,129,26,0) 72%);
  transform:translateZ(-1px);
}
.esys__plane[data-plane="core"]::before{
  border-color:rgba(232,180,90,.3);
  background:linear-gradient(90deg, rgba(232,180,90,.11), rgba(196,129,26,.02) 78%);
}

.esys__ptag{
  position:absolute; left:-2%; top:-30px;
  font-family:var(--font-body); font-size:9px; letter-spacing:.26em;
  text-transform:uppercase; color:rgba(59,27,12,.62); white-space:nowrap;
  transform:rotateZ(calc(-1 * var(--cam-z))) rotateX(calc(-1 * var(--cam-x)));
  transform-origin:left center;
}

/* ── nodes ────────────────────────────────────────────────── */
.esys__node{
  position:absolute; top:0; left:var(--nx);
  width:var(--r,14px); height:var(--r,14px); margin:calc(var(--r,14px) / -2);
  border-radius:50%;
  background:var(--amber);
  opacity:calc(var(--o,.85) * var(--dim));
  transform:translateZ(0) scale(var(--s,1));
  transition:opacity .7s var(--ease), box-shadow .7s var(--ease);
  will-change:transform;
}
.esys__node--ring{
  background:none; border:1.5px solid var(--amber);
}
.esys__node--core{
  background:var(--amber-light);
  box-shadow:0 0 0 calc(6px + var(--w-grid) * 8px) rgba(232,180,90,.09);
}
.esys__label{
  position:absolute; left:50%; top:calc(100% + 9px);
  transform:translateX(-50%) rotateZ(calc(-1 * var(--cam-z))) rotateX(calc(-1 * var(--cam-x)));
  transform-origin:center top;
  font-family:var(--font-body); font-size:9.5px; letter-spacing:.16em;
  text-transform:uppercase; color:rgba(59,27,12,.6); white-space:nowrap;
  opacity:var(--dim);
  transition:opacity .5s var(--ease), color .5s var(--ease);
}
.esys__node[data-lit="1"]{ opacity:1; }
.esys__node[data-lit="1"] .esys__label{ opacity:1; color:var(--amber-light); }

/* storage fill: a partial ring that visibly charges and discharges */
.esys__fill{
  position:absolute; inset:-6px; border-radius:50%;
  border:1.5px solid transparent;
  border-top-color:var(--amber-light);
  border-right-color:var(--amber-light);
  opacity:calc(.25 + var(--w-store) * .75);
  transform:rotate(calc(-90deg + var(--w-store) * 260deg));
  transition:transform 1.6s var(--ease), opacity 1.6s var(--ease);
}

/* breathing scale, applied per category from the weights */
.esys__plane[data-plane="gen"]  .esys__node{ --s:calc(1 + var(--w-gen) * .30); }
.esys__plane[data-plane="load"] .esys__node{ --s:calc(1 + var(--w-load) * .30); }
.esys__plane[data-plane="store"].esys__plane .esys__node{ --s:calc(.94 + var(--w-store) * .26); }
.esys__plane[data-plane="core"] .esys__node{ --s:calc(1 + var(--w-grid) * .12); }
.esys__node{ transition:transform 1.8s var(--ease), opacity .7s var(--ease); }

/* ── link overlay (screen space) ──────────────────────────── */
.esys__links{
  position:absolute; inset:0; width:100%; height:100%;
  pointer-events:none; overflow:visible;
}
.esys__link{ fill:none; stroke:var(--amber); stroke-linecap:round; }
.esys__link[data-kind="gen"]  { stroke-width:calc(.7px + var(--w-gen)   * 1.7px); opacity:calc((.16 + var(--w-gen)   * .5) * var(--dim)); }
.esys__link[data-kind="load"] { stroke-width:calc(.7px + var(--w-load)  * 1.7px); opacity:calc((.16 + var(--w-load)  * .5) * var(--dim)); }
.esys__link[data-kind="store"]{ stroke-width:calc(.7px + var(--w-store) * 1.4px); opacity:calc((.14 + var(--w-store) * .45) * var(--dim)); }
.esys__link[data-kind="grid"] { stroke-width:calc(.9px + var(--w-grid)  * 2.1px); opacity:calc((.2  + var(--w-grid)  * .55) * var(--dim)); }
.esys__link[data-kind="recover"]{
  stroke:var(--amber-light); stroke-width:1.4px; stroke-dasharray:5 7;
  opacity:calc(var(--w-recover) * .9 * var(--dim));
}
.esys__link[data-lit="1"]{ opacity:1 !important; }

/* travelling energy pulses */
.esys__pulse{
  fill:none; stroke:var(--amber-light); stroke-width:2.4; stroke-linecap:round;
  opacity:0;
}
@media (prefers-reduced-motion: no-preference){
  .esys__pulse{ animation:esysPulse 5.4s linear infinite; animation-delay:var(--pd,0s); }
}
@keyframes esysPulse{
  0%  { stroke-dashoffset:var(--plen,620px); opacity:0 }
  8%  { opacity:.85 }
  62% { opacity:.85 }
  74% { stroke-dashoffset:0; opacity:0 }
  100%{ stroke-dashoffset:0; opacity:0 }
}

/* the modelled target state, shown while comparing */
.esys__ghost{
  fill:none; stroke:var(--dust); stroke-width:1; stroke-dasharray:2 6;
  opacity:calc(var(--ghost,0) * .5);
  transition:opacity .8s var(--ease);
}

/* ── scroll chapters ──────────────────────────────────────── */
.esys-scroll{ position:relative; background:var(--parchment); }
.esys-sticky{
  position:sticky; top:0; height:100svh;
  display:grid; grid-template-rows:1fr auto; overflow:hidden;
}
.esys-sticky .esys{ height:100%; min-height:0; }
/* Grid-Item muss unter seine Inhaltshoehe schrumpfen duerfen, sonst schiebt
   die SVG-Eigenhoehe die Kapitelzeile unter den Sticky-Rand (overflow:hidden
   schneidet dann die letzte Textzeile ab). */
.esys-sticky .netbuild{ height:100%; min-height:0; }
.esys-chapters{
  position:relative; z-index:3;
  max-width:1280px; width:100%; margin:0 auto;
  padding:0 var(--sp-4) var(--sp-7); min-height:168px;
}
.esys-chapter{
  position:absolute; left:var(--sp-4); right:var(--sp-4); bottom:var(--sp-7);
  opacity:0; transform:translateY(14px);
  transition:opacity .55s var(--ease), transform .55s var(--ease);
  pointer-events:none;
}
.esys-chapter.is-on{ opacity:1; transform:none; }
.esys-chapter small{
  display:block; font-size:10px; letter-spacing:.3em; text-transform:uppercase;
  color:var(--amber-text); margin-bottom:10px;
}
.esys-chapter h3{
  font-family:var(--font-head); font-weight:300; color:var(--cacao);
  font-size:clamp(1.7rem,3.6vw,3rem); line-height:1.05; margin:0 0 8px;
}
.esys-chapter p{ font-size:.96rem; color:var(--ink-soft); max-width:46ch; margin:0; }

/* progress ticks */
.esys-ticks{
  position:absolute; right:var(--sp-4); top:50%; transform:translateY(-50%);
  z-index:3; display:flex; flex-direction:column; gap:10px;
}
.esys-ticks i{
  display:block; width:18px; height:1px; background:rgba(59,27,12,.22);
  transition:background .4s var(--ease), width .4s var(--ease);
}
.esys-ticks i.is-on{ background:var(--amber); width:30px; }

/* the priorities that remain in the final chapter */
.esys-priorities{
  position:absolute; left:50%; top:50%; z-index:2;
  transform:translate(-50%,-50%);
  display:flex; gap:clamp(var(--sp-4),5vw,var(--sp-7));
  opacity:0; pointer-events:none;
  transition:opacity .7s var(--ease);
}
.esys-priorities.is-on{ opacity:1; }
.esys-priorities div{ text-align:center; }
.esys-priorities b{
  display:block; font-family:var(--font-head); font-style:italic;
  font-size:clamp(1.8rem,4vw,3.2rem); color:var(--amber-light); line-height:1;
}
.esys-priorities span{
  display:block; margin-top:8px; font-size:10.5px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--amber-text);
}

/* ── legend: doubles as the hover control on desktop ──────── */
.esys-legend{
  display:flex; flex-wrap:wrap; gap:var(--sp-3) var(--sp-5);
  margin-top:var(--sp-6); padding-top:var(--sp-4);
  border-top:1px solid rgba(59,27,12,.16);
}
.esys-legend span{
  font-size:10.5px; letter-spacing:.22em; text-transform:uppercase;
  color:var(--cacao); cursor:default;
  transition:color .3s var(--ease);
}
.esys-legend span:hover{ color:var(--amber-light); }

/* ── applications: list + one shared system ───────────────── */
.apps__grid{
  display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(var(--sp-5),4vw,var(--sp-7)); align-items:start; margin-top:var(--sp-6);
}
@media (max-width:1000px){ .apps__grid{ grid-template-columns:1fr; } }
.apps__grid .applist{ margin-top:0; }
.apps__vis{ position:sticky; top:104px; }
@media (max-width:1000px){ .apps__vis{ position:static; margin-top:var(--sp-6); } }
.apps__vis .esys, .split__vis .esys{
  height:clamp(380px,40vw,500px);
  --cam-scale:.78; --cam-x:17deg; --cam-z:-4deg;
}

.apps__vis .esys__label, .split__vis .esys__label{ font-size:8.5px; letter-spacing:.1em; }
.apps__vis .esys__ptag, .split__vis .esys__ptag{ font-size:8px; letter-spacing:.16em; }
.apps__hint{
  margin-top:var(--sp-4); font-size:10.5px; letter-spacing:.18em;
  text-transform:uppercase; color:var(--amber-text); text-align:center;
}
.applist a.is-active{ background:rgba(196,129,26,.09); padding-left:var(--sp-4); }
.applist__open .go{ color:var(--amber-text); }

/* ── the scrubbed stage needs room to scrub in ────────────── */
.esys-scroll{ min-height:340vh; }
@media (max-width:900px){ .esys-scroll{ min-height:0; } }
@media (prefers-reduced-motion: reduce){ .esys-scroll{ min-height:0; } }
html:not(.js) .esys-scroll{ min-height:0; }
.esys-intro{ padding-bottom:var(--sp-5); }

/* ── compact variant (inline, no scroll scrub) ────────────── */
.esys--compact{ height:clamp(380px,46vw,520px); }
.esys--compact .esys__label{ font-size:9px; }

/* ── mobile: flatter, taller, no pointer, no scrub ────────── */
@media (max-width:900px){
  .esys{ --cam-x:8deg; --cam-z:0deg; --cam-scale:.66; }
  .esys__label{ letter-spacing:.06em; }
  .esys__plane .esys__node:nth-child(odd) .esys__label{ top:calc(100% + 20px); }
  .esys__space{ perspective:900px; }
  .esys__plane{ left:4%; right:4%; }
  .esys__plane::before{ top:-26px; height:52px; }
  .esys__label{ font-size:8.5px; letter-spacing:.1em; }
  .esys__ptag{ font-size:8px; letter-spacing:.18em; }
  .esys-sticky{ position:static; height:auto; }
  .esys-sticky .esys{ height:clamp(400px,84vw,560px); }
  .esys-chapters{ position:static; padding:var(--sp-5) var(--sp-4) 0; min-height:0; }
  .esys-chapter{ position:static; opacity:1; transform:none; margin-bottom:var(--sp-5); }
  .esys-ticks{ display:none; }
  .esys-priorities{ position:static; transform:none; opacity:1;
    justify-content:space-between; padding:var(--sp-5) var(--sp-4) 0; }
}

/* ── reduced motion: a coherent, readable static system ───── */
@media (prefers-reduced-motion: reduce){
  .esys{ --w-gen:.62; --w-load:.62; --w-store:.55; --w-recover:.8; --w-grid:.6; }
  .esys__world{ transition:none; }
  .esys__node, .esys__fill{ transition:none; }
  .esys__pulse{ display:none; }
  .esys-sticky{ position:static; height:auto; }
  .esys-sticky .esys{ height:clamp(420px,60vw,600px); }
  .esys-chapters{ position:static; padding-top:var(--sp-5); min-height:0; }
  .esys-chapter{ position:static; opacity:1; transform:none; margin-bottom:var(--sp-4); }
  .esys-ticks{ display:none; }
  .esys-priorities{ position:static; transform:none; opacity:1; padding-top:var(--sp-5); }
  .esys__ghost{ opacity:.28; }
}

/* no JS: the model still renders as a static diagram */
html:not(.js) .esys__pulse{ display:none; }
html:not(.js) .esys-chapter{ position:static; opacity:1; transform:none; margin-bottom:var(--sp-4); }
html:not(.js) .esys-sticky{ position:static; height:auto; }
html:not(.js) .esys-priorities{ position:static; transform:none; opacity:1; }

/* ============================================================
   NETBUILD — the local network assembling itself while scrolling
   ============================================================ */
.netbuild{ --stage:1; position:relative; width:100%; height:100%; }
.netbuild svg{ width:100%; height:100%; display:block; overflow:visible; }
.netbuild [data-step]{
  /* opacity clamps itself: stage >= step -> 1, otherwise 0 */
  opacity:calc((var(--stage) - var(--step) + 1) * 12);
  transition:opacity .85s var(--ease);
}
.netbuild .nb-edge{ fill:none; stroke:var(--amber); stroke-width:1.1; }
.netbuild .nb-edge--soft{ stroke:var(--dust); stroke-width:1; }
.netbuild .nb-node{ fill:var(--amber); }
.netbuild .nb-node--out{ fill:none; stroke:var(--amber); stroke-width:1.5; }
.netbuild .nb-node--goal{ fill:var(--amber); }
.netbuild .nb-label{
  font-family:var(--font-body); font-size:11px; letter-spacing:.18em;
  text-transform:uppercase; fill:rgba(59,27,12,.6);
}
.netbuild .nb-label--goal{ fill:var(--amber-light); }
.netbuild .nb-pulse{
  fill:none; stroke:var(--amber-light); stroke-width:2.2; stroke-linecap:round;
  stroke-dasharray:3 900;
}
@media (prefers-reduced-motion: no-preference){
  .netbuild .nb-pulse{ animation:esysPulse 6s linear infinite; animation-delay:var(--pd,0s); }
}
@media (prefers-reduced-motion: reduce){
  .netbuild{ --stage:5 !important; }
  .netbuild .nb-pulse{ display:none; }
}
html:not(.js) .netbuild{ --stage:5; }
@media (max-width:900px){
  .netbuild .nb-label{ font-size:15px; letter-spacing:.1em; }
}

/* section heading that lives inside a sticky stage */
.esys-h2{
  position:absolute; left:var(--sp-4); top:calc(-1 * var(--sp-8));
  font-family:var(--font-body); font-weight:400;
  font-size:11px; letter-spacing:.32em; text-transform:uppercase;
  color:var(--ink-soft); margin:0;
}
@media (max-width:900px){
  .esys-h2{ position:static; margin-bottom:var(--sp-4); }
}
@media (prefers-reduced-motion: reduce){
  .esys-h2{ position:static; margin-bottom:var(--sp-4); }
}
html:not(.js) .esys-h2{ position:static; margin-bottom:var(--sp-4); }

/* pulses animate their own opacity, so gate them on stroke-opacity instead */
.netbuild .nb-pulse{ stroke-opacity:calc((var(--stage) - var(--step) + 1) * 12); }
