<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>