<title>SIEC · Wann wird Konzentration zum Problem? (HHI)</title>
<style>
  :root{
    --page:#ECECEA; --card:#FFFFFF; --ink:#1F1F1F; --text:#595959; --muted:#8C8C8C;
    --line:#E4E4E1; --red:#AF1A1D; --red-dark:#570D0E; --green:#2F6B2F; --sand:#CFAF8A; --gray:#BFBFBF;
    --sans:"Inter",system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  }
  *{box-sizing:border-box;}
  body{ margin:0; min-height:100vh; padding:24px; display:flex; align-items:center; justify-content:center;
    background:var(--page); font-family:var(--sans); color:var(--text); }
  .wrap{ width:100%; max-width:740px; background:var(--card); border:1px solid var(--line);
    border-radius:10px; padding:clamp(24px,4vw,40px); -webkit-font-smoothing:antialiased; }
  .eyebrow{ font-size:.72rem; letter-spacing:.2em; text-transform:uppercase; color:var(--red); font-weight:600; margin:0 0 14px; }
  h1{ font-size:clamp(1.55rem,3.4vw,2.05rem); line-height:1.14; letter-spacing:-.01em; font-weight:300; color:var(--ink); margin:0 0 12px; }
  .sub{ font-size:1rem; line-height:1.55; margin:0 0 24px; max-width:60ch; }

  canvas{ width:100%; height:320px; display:block; }

  .stats{ display:grid; grid-template-columns:repeat(3,1fr); gap:1px; background:var(--line);
    border:1px solid var(--line); border-radius:8px; overflow:hidden; margin:18px 0 0; }
  .stat{ background:var(--card); padding:15px 16px; }
  .stat .k{ font-size:.68rem; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin:0 0 7px; }
  .stat .v{ font-size:1.7rem; line-height:1; font-weight:600; color:var(--ink);
    font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1; }
  .stat .u{ font-size:.72rem; color:var(--muted); margin-top:7px; }

  .note{ margin:16px 0 0; padding:12px 16px; border-left:3px solid var(--red);
    background:rgba(175,26,29,.05); border-radius:0 8px 8px 0; font-size:.92rem; line-height:1.45; color:var(--text); }

  .market{ margin:24px 0 0; }
  .mlabel{ font-size:.78rem; color:var(--muted); margin:0 0 7px; }
  .bar{ display:flex; height:34px; border-radius:6px; overflow:hidden; border:1px solid var(--line); }
  .seg{ display:flex; align-items:center; justify-content:center; font-size:.72rem; font-weight:600;
    white-space:nowrap; overflow:hidden; min-width:0; }

  .controls{ margin:20px 0 0; }
  .sliderrow{ display:flex; align-items:baseline; justify-content:space-between; margin:18px 0 8px; }
  .sliderrow label{ font-size:.82rem; letter-spacing:.03em; color:var(--text); }
  .sliderrow .n{ font-size:1.02rem; font-weight:600; color:var(--ink); font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1; }
  input[type=range]{ -webkit-appearance:none; appearance:none; width:100%; height:5px; border-radius:5px; background:var(--line); outline:none; }
  input[type=range]::-webkit-slider-thumb{ -webkit-appearance:none; appearance:none; width:20px; height:20px; border-radius:50%;
    background:var(--card); border:4px solid var(--red); cursor:pointer; transition:transform .12s; }
  input[type=range]::-webkit-slider-thumb:hover{ transform:scale(1.08); }
  input[type=range]::-moz-range-thumb{ width:16px; height:16px; border-radius:50%; background:var(--card); border:4px solid var(--red); cursor:pointer; }
  input[type=range]:focus-visible{ box-shadow:0 0 0 3px rgba(175,26,29,.3); }

  .btns{ display:flex; gap:10px; margin:22px 0 0; flex-wrap:wrap; }
  button{ font-family:var(--sans); font-size:.92rem; font-weight:500; cursor:pointer; border-radius:7px;
    padding:11px 17px; border:1px solid transparent; transition:background .15s, color .15s, border-color .15s; }
  .primary{ background:var(--red); color:#fff; }
  .primary:hover{ background:var(--red-dark); }
  .ghost{ background:transparent; color:var(--text); border-color:var(--line); }
  .ghost:hover{ color:var(--ink); border-color:var(--muted); }
  button:focus-visible{ outline:none; box-shadow:0 0 0 3px rgba(175,26,29,.3); }

  @media (max-width:520px){ .stats{ grid-template-columns:1fr; } .stat .v{ font-size:1.45rem; } }
</style>

<div class="wrap">
  <p class="eyebrow">SIEC · Fusionskontrolle interaktiv</p>
  <h1>Wann wird Konzentration zum Problem?</h1>
  <p class="sub">Der Herfindahl-Hirschman-Index (HHI) misst die Marktkonzentration als Summe der quadrierten Marktanteile. Für die Fusionskontrolle zählen zwei Grössen: das Niveau nach der Fusion und die Veränderung (ΔHHI = 2 × Anteil A × Anteil B). Verschieben Sie die Anteile der fusionierenden Anbieter und vergleichen Sie das Ergebnis mit den Schwellen der EU-Horizontalleitlinien.</p>

  <canvas id="plane" aria-hidden="true"></canvas>

  <div class="stats" role="group" aria-live="polite" aria-label="HHI-Ergebnis">
    <div class="stat">
      <p class="k">HHI nach Fusion</p>
      <p class="v" id="hhi">–</p>
      <p class="u" id="hhipre">–</p>
    </div>
    <div class="stat">
      <p class="k">ΔHHI</p>
      <p class="v" id="delta">–</p>
      <p class="u">= 2 × A × B</p>
    </div>
    <div class="stat">
      <p class="k">Einordnung</p>
      <p class="v" id="zone" style="font-size:1.05rem;">–</p>
      <p class="u">EU-Schwellen</p>
    </div>
  </div>

  <p class="note" id="note"></p>

  <div class="controls">
    <div class="market">
      <p class="mlabel" id="mcap">Markt vor der Fusion</p>
      <div class="bar" id="bar"></div>
    </div>

    <div class="sliderrow">
      <label for="sa">Marktanteil Anbieter A</label>
      <span class="n"><span id="aval">20</span> %</span>
    </div>
    <input type="range" id="sa" min="0" max="50" step="1" value="20" aria-describedby="aval" />

    <div class="sliderrow">
      <label for="sb">Marktanteil Anbieter B</label>
      <span class="n"><span id="bval">15</span> %</span>
    </div>
    <input type="range" id="sb" min="0" max="50" step="1" value="15" aria-describedby="bval" />

    <div class="btns">
      <button class="primary" id="big">Zwei grosse Anbieter</button>
      <button class="ghost" id="small">Zwei kleine Anbieter</button>
      <button class="ghost" id="reset">Zurücksetzen</button>
    </div>
  </div>
</div>

<script>
(function(){
  "use strict";
  function clamp(x,a,b){ return Math.max(a, Math.min(b, x)); }

  function model(A,B){
    var rest = Math.max(0, 100 - A - B);
    var k = rest>0 ? Math.max(1, Math.round(rest/10)) : 0;
    var restHHI = k>0 ? rest*rest/k : 0;
    var pre  = A*A + B*B + restHHI;
    var post = (A+B)*(A+B) + restHHI;
    var delta = post - pre;                 // = 2*A*B
    var safe = (post<1000) || (post<=2000 && delta<250) || (post>2000 && delta<150);
    return { rest:rest, k:k, pre:pre, post:post, delta:delta, safe:safe };
  }
  function verdictColor(s){ return s ? "#2F6B2F" : "#AF1A1D"; }

  var xMax=5500, yMax=2500;
  var cv=document.getElementById("plane"), ctx=cv.getContext("2d"), cw=0, ch=0;
  function setup(){
    var dpr=window.devicePixelRatio||1;
    cw=cv.clientWidth; ch=cv.clientHeight;
    cv.width=Math.round(cw*dpr); cv.height=Math.round(ch*dpr);
    ctx.setTransform(dpr,0,0,dpr,0,0);
    draw(state.a,state.b);
  }

  function draw(A,B){
    var m=model(A,B);
    var w=cw,h=ch, L=52,R=16,T=18,Bm=36, pw=w-L-R, ph=h-T-Bm;
    function X(v){ return L+(v/xMax)*pw; }
    function Y(v){ return T+(1-v/yMax)*ph; }
    ctx.clearRect(0,0,w,h);

    // Safe-Harbour-Grundfläche (grün)
    ctx.fillStyle="rgba(47,107,47,.07)"; ctx.fillRect(L,T,pw,ph);
    // Prüfzonen (rot): HHI 1000–2000 & Δ≥250 ; HHI>2000 & Δ≥150
    ctx.fillStyle="rgba(175,26,29,.09)";
    ctx.fillRect(X(1000), T, X(2000)-X(1000), Y(250)-T);
    ctx.fillRect(X(2000), T, X(xMax)-X(2000), Y(150)-T);

    // Gitter
    ctx.strokeStyle="rgba(0,0,0,.05)"; ctx.lineWidth=1;
    [1000,2000,3000,4000,5000].forEach(function(v){ ctx.beginPath(); ctx.moveTo(X(v),T); ctx.lineTo(X(v),T+ph); ctx.stroke(); });
    [500,1000,1500,2000].forEach(function(v){ ctx.beginPath(); ctx.moveTo(L,Y(v)); ctx.lineTo(L+pw,Y(v)); ctx.stroke(); });

    // Schwellen-Linien
    ctx.strokeStyle="rgba(120,120,120,.8)"; ctx.lineWidth=1.5; ctx.setLineDash([5,5]);
    ctx.beginPath(); ctx.moveTo(X(1000),T); ctx.lineTo(X(1000),T+ph); ctx.stroke();
    ctx.beginPath(); ctx.moveTo(X(2000),T); ctx.lineTo(X(2000),T+ph); ctx.stroke();
    ctx.setLineDash([]);
    ctx.strokeStyle="rgba(175,26,29,.75)"; ctx.lineWidth=1.5;
    ctx.beginPath(); ctx.moveTo(X(1000),Y(250)); ctx.lineTo(X(2000),Y(250)); ctx.stroke();
    ctx.beginPath(); ctx.moveTo(X(2000),Y(150)); ctx.lineTo(X(xMax),Y(150)); ctx.stroke();

    ctx.fillStyle="rgba(175,26,29,.85)"; ctx.font='600 10px "Inter",system-ui,sans-serif'; ctx.textAlign="left";
    ctx.fillText("Δ 250", X(1000)+4, Y(250)-5);
    ctx.fillText("Δ 150", X(2000)+4, Y(150)-5);
    ctx.fillStyle="rgba(47,107,47,.9)"; ctx.fillText("Safe Harbour", L+6, T+ph-8);

    // aktueller Punkt (geklemmt für die Darstellung)
    var px=X(clamp(m.post,0,xMax)), py=Y(clamp(m.delta,0,yMax)), col=verdictColor(m.safe);
    ctx.strokeStyle="rgba(0,0,0,.18)"; ctx.setLineDash([3,3]); ctx.lineWidth=1;
    ctx.beginPath(); ctx.moveTo(px,py); ctx.lineTo(px,T+ph); ctx.stroke();
    ctx.beginPath(); ctx.moveTo(px,py); ctx.lineTo(L,py); ctx.stroke(); ctx.setLineDash([]);
    ctx.fillStyle=col; ctx.beginPath(); ctx.arc(px,py,6,0,Math.PI*2); ctx.fill();
    ctx.strokeStyle="#fff"; ctx.lineWidth=2; ctx.stroke();

    // Achsen
    ctx.fillStyle="#8C8C8C"; ctx.font='10px "Inter",system-ui,sans-serif';
    ctx.textAlign="center";
    [0,1000,2000,3000,4000,5000].forEach(function(v){ ctx.fillText(v, X(v), T+ph+16); });
    ctx.fillText("HHI nach der Fusion  →", L+pw/2, T+ph+30);
    ctx.textAlign="right";
    [500,1000,1500,2000].forEach(function(v){ ctx.fillText(v, L-8, Y(v)+3); });
    ctx.save(); ctx.translate(13,T+ph/2); ctx.rotate(-Math.PI/2); ctx.textAlign="center";
    ctx.fillText("ΔHHI", 0, 0); ctx.restore();
  }

  // --- Zustand & UI ---
  var state={ a:20, b:15 };
  var elH=document.getElementById("hhi"), elHpre=document.getElementById("hhipre"),
      elD=document.getElementById("delta"), elZone=document.getElementById("zone"),
      elNote=document.getElementById("note"), elA=document.getElementById("aval"), elB=document.getElementById("bval"),
      sA=document.getElementById("sa"), sB=document.getElementById("sb"),
      bar=document.getElementById("bar"), mcap=document.getElementById("mcap"),
      bBig=document.getElementById("big"), bSmall=document.getElementById("small"), bReset=document.getElementById("reset");

  function seg(w, bg, color, label){
    var d=document.createElement("div");
    d.className="seg"; d.style.flexBasis=w+"%"; d.style.background=bg; d.style.color=color;
    if(w>=9) d.textContent=label;
    return d;
  }
  function drawBar(A,B,m){
    bar.innerHTML="";
    bar.appendChild(seg(A, "var(--red)", "#fff", "A "+A+"%"));
    bar.appendChild(seg(B, "var(--red-dark)", "#fff", "B "+B+"%"));
    if(m.rest>0) bar.appendChild(seg(m.rest, "#BFBFBF", "#3A3A3A", m.k+" übrige"));
    mcap.textContent = "Markt vor der Fusion — Fusion: A ("+A+" %) + B ("+B+" %), Rest auf "+m.k+" Anbieter verteilt";
  }

  function render(){
    var A=state.a, B=state.b, m=model(A,B), col=verdictColor(m.safe);
    elH.textContent=Math.round(m.post); elH.style.color=col;
    elHpre.textContent="vor der Fusion: "+Math.round(m.pre);
    elD.textContent="+"+Math.round(m.delta);
    elZone.textContent=m.safe ? "Safe Harbour" : "nähere Prüfung"; elZone.style.color=col;
    elNote.textContent = m.safe
      ? "Im Safe Harbour der EU-Leitlinien – Niveau und Veränderung sind gering genug, eine vertiefte Prüfung erübrigt sich meist."
      : "Über den EU-Schwellen: hier ist eine vertiefte Prüfung angezeigt. Beachten Sie aber – der HHI misst nur die Struktur, nicht die Nähe der Wettbewerber (dafür der GUPPI).";
    elNote.style.borderLeftColor=col;
    elA.textContent=A; elB.textContent=B; sA.value=A; sB.value=B;
    drawBar(A,B,m);
    draw(A,B);
  }

  var reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  var anim=null;
  function animateTo(aT,bT){
    if(reduce){ state.a=aT; state.b=bT; render(); return; }
    if(anim) cancelAnimationFrame(anim);
    var a0=state.a, b0=state.b, t0=null, dur=520;
    function step(ts){
      if(t0===null)t0=ts;
      var k=clamp((ts-t0)/dur,0,1), e=1-Math.pow(1-k,3);
      state.a=Math.round(a0+(aT-a0)*e); state.b=Math.round(b0+(bT-b0)*e);
      render();
      if(k<1){ anim=requestAnimationFrame(step); } else { state.a=aT; state.b=bT; render(); }
    }
    anim=requestAnimationFrame(step);
  }

  sA.addEventListener("input", function(){ state.a=parseInt(sA.value,10); render(); });
  sB.addEventListener("input", function(){ state.b=parseInt(sB.value,10); render(); });
  bBig.addEventListener("click", function(){ animateTo(35,25); });
  bSmall.addEventListener("click", function(){ animateTo(8,7); });
  bReset.addEventListener("click", function(){ animateTo(20,15); });

  window.addEventListener("resize", setup);
  setup(); render();
})();
</script>