Widget:Solvency2 BalanceSheet: Difference between revisions

Content deleted Content added
Created page with "<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Solvency II Balance Sheet</title> <link href="https://fonts.googleapis.com/css2?family=DM+Serif+Display&family=IBM+Plex+Sans:wght@300;400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet"> <style> :root { --bg: #0c1018; --surface: #141b27; --surface2: #1a2234; --border: #253044; --tex..."
 
No edit summary
Line 5:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Solvency II Balance Sheet</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Serif+Display&family=IBM+Plex+Sans:wght@300;400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
--bg: #0c1018ffffff;
--surface: #141b27f8f9fa;
--surface2: #1a2234eaecf0;
--border: #253044a2a9b1;
--textborder-heavy: #e2e8f0202122;
--text-dim: #8896ab202122;
--text-muteddim: #5a6a8054595d;
--accenttext-bluemuted: #4a9eff72777d;
--accent-cyanlink: #22d3ee000099;
 
--accent-emerald: #34d399;
/* Monochrome block palette — dark-to-light for visual hierarchy */
--accent-amber: #fbbf24;
--accentassets-rosefill: #fb7185202122;
--accentbel-violetfill: #a78bfa54595d;
--accentrm-orangefill: #fb923c72777d;
--scr-fill: #a2a9b1;
/* Balance sheet colors */
--assetsmcr-colorfill: #4a9effc8ccd1;
--belsurplus-colorfill: #fb923ceaecf0;
--rm-color: #fbbf24;
--scr-color: #fb7185;
--mcr-color: #e879a0;
--surplus-color: #34d399;
--own-funds-color: #22d3ee;
--tp-color: #f59e42;
}
 
Line 38 ⟶ 31:
background: var(--bg);
color: var(--text);
font-family: 'IBM Plex Sans', sans-serif;
minline-height: 100vh1.6;
-webkit-font-smoothing: auto;
overflow-x: hidden;
}
 
/* Grain overlay */
body::before {
content: '';
position: fixed;
inset: 0;
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.04'/%3E%3C/svg%3E");
pointer-events: none;
z-index: 999;
}
 
.container {
max-width: 1280px900px;
margin: 0 auto;
padding: 40px24px 32px16px 60px;
}
 
/* ---- Header ---- */
header {
border-bottom: 2px solid var(--border-heavy);
text-align: center;
marginpadding-bottom: 48px10px;
margin-bottom: 20px;
animation: fadeUp 0.8s ease-out;
}
 
header .eyebrow {
font-family: 'IBM Plex Mono', monospace;
font-size: 11px;
font-weight: 500;
letter-spacing: 3px;
text-transform: uppercase;
color: var(--accent-cyan);
margin-bottom: 16px;
opacity: 0.8;
}
 
header h1 {
font-familysize: 'DM Serif Display', serif1.8em;
font-sizeweight: clamp(28px, 5vw, 48px)bold;
font-weightcolor: 400var(--text);
line-height: 1.1525;
letter-spacingmargin: -0.5px;
background: linear-gradient(135deg, #e2e8f0 30%, var(--accent-cyan) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 12px;
}
 
header p {
font-size: 15px0.88em;
color: var(--text-dim);
maxmargin-widthtop: 640px4px;
marginline-height: 0 auto1.6;
line-height: 1.65;
font-weight: 300;
}
 
/* Main---- Two-column master layout ---- */
.main-grid {
display: grid;
grid-template-columns: 1fr 360px300px;
gap: 32px24px;
align-items: start;
animation: fadeUp 0.8s ease-out 0.15s both;
}
@media (max-width: 760px) {
 
@media (max-width: 960px) {
.main-grid { grid-template-columns: 1fr; }
}
 
/* Balance---- Balance-sheet visual ---- */
.bs-visual {
background: var(--surface);
border: 1px solid var(--border);
border-radiusbackground: 16pxvar(--bg);
padding: 36px20px 24px 16px;
position: relative;
overflow: hidden;
}
 
.bs-visual::before {
content: '';
position: absolute;
top: -1px;
left: 40px;
right: 40px;
height: 1px;
background: linear-gradient(90deg, transparent, var(--accent-cyan), transparent);
opacity: 0.4;
}
 
Line 135 ⟶ 85:
display: flex;
justify-content: space-between;
margin-bottom: 28px14px;
}
 
.bs-col-label {
font-familysize: 'IBM Plex Mono', monospace0.78em;
font-sizeweight: 11pxbold;
fontletter-weightspacing: 5000.06em;
letter-spacing: 2.5px;
text-transform: uppercase;
color: var(--text-muted);
Line 149 ⟶ 98:
.bs-columns {
display: grid;
grid-template-columns: 1fr 32px24px 1fr;
gapmin-height: 0480px;
min-height: 520px;
}
 
Line 157 ⟶ 105:
display: flex;
flex-direction: column;
gap: 3px2px;
}
 
.bs-separator {
display: flex;
align-items: centerstretch;
justify-content: center;
}
 
.bs-separator .line {
width: 1px;
height: 100%;
background: var(--border);
opacity: 0.5;
}
 
/* ---- Blocks ---- */
.bs-block {
border-radiuspadding: 10px12px 14px;
padding: 16px 18px;
position: relative;
cursor: pointer;
transition: allbackground 0.3s2s cubic-bezier(0.22ease, 1,box-shadow 0.36,2s 1)ease;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: center;
border: 1px solid transparent;
color: #fff;
}
 
.bs-block::before {
content: '';
position: absolute;
inset: 0;
opacity: 0.08;
transition: opacity 0.3s ease;
}
 
.bs-block:hover {
transform: translateX(3px);
border-color: rgba(255,255,255,0.08);
}
 
.bs-block:hover::before { opacity: 0.14; }
 
.bs-block.active {
border-color: rgba(255,255,255,0.15);
box-shadow: 0 0 24px rgba(0,0,0,0.3);
transform: scale(1.02);
z-index: 2;
}
 
.bs-block .label {
font-size: 13px0.82em;
font-weight: 600bold;
letterline-spacingheight: 01.2px3;
margin-bottom: 3px;
position: relative;
}
 
.bs-block .sublabel {
font-size: 11px0.72em;
opacity: 0.675;
fontmargin-weighttop: 4001px;
position: relative;
}
 
.bs-block .value {
font-familysize: 'IBM Plex Mono', monospace0.88em;
font-sizeweight: 15pxbold;
fontmargin-weighttop: 5004px;
font-variant-numeric: tabular-nums;
margin-top: 6px;
position: relative;
}
 
.bs-block:hover {
/* Block specific colors */
box-shadow: 0 0 0 2px var(--border-heavy);
.block-assets {
z-index: 2;
background: rgba(74, 158, 255, 0.12);
border-color: rgba(74, 158, 255, 0.15);
}
.bs-block.active {
.block-assets::before { background: var(--assets-color); }
.block box-assetsshadow: .value0 {0 color:0 2.5px var(--assetsborder-colorheavy); }
z-index: 3;
 
.block-bel {
background: rgba(251, 146, 60, 0.1);
}
.block-bel::before { background: var(--bel-color); }
.block-bel .value { color: var(--bel-color); }
 
./* Individual block-rm {fills */
.block-assets { background: rgbavar(251, 191, 36, 0.1--assets-fill); }
.block-bel { background: var(--bel-fill); }
}
.block-rm::before { background: var(--rm-colorfill); }
.block-rmscr .value { colorbackground: var(--rmscr-fill); color: var(--text); }
.block-mcr { background: var(--mcr-fill); color: var(--text); }
.block-surplus { background: var(--surplus-fill); color: var(--text); border: 1px solid var(--border); }
 
/* ---- Legend ---- */
.block-scr {
.legend-strip {
background: rgba(251, 113, 133, 0.1);
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-top: 16px;
border-top: 1px solid var(--border);
padding-top: 12px;
}
.legend-item {
.block-scr::before { background: var(--scr-color); }
display: flex;
.block-scr .value { color: var(--scr-color); }
align-items: center;
 
gap: 5px;
.block-mcr {
padding: 3px 8px;
background: rgba(167, 139, 250, 0.1);
font-size: 0.75em;
color: var(--text-dim);
cursor: pointer;
border: 1px solid transparent;
border-radius: 2px;
transition: border-color 0.15s ease;
}
.blocklegend-mcritem::beforehover { backgroundborder-color: var(--accent-violetborder); }
.legend-dot {
.block-mcr .value { color: var(--accent-violet); }
width: 10px; height: 10px;
 
border-radius: 1px;
.block-surplus {
flex-shrink: 0;
background: rgba(52, 211, 153, 0.1);
}
.block-surplus::before { background: var(--surplus-color); }
.block-surplus .value { color: var(--surplus-color); }
 
/* ---- Status bar ---- */
.block-tp {
.status-bar {
background: rgba(245, 158, 66, 0.08);
display: flex;
border-color: rgba(245, 158, 66, 0.12);
gap: 16px;
}
flex-wrap: wrap;
 
margin-top: 12px;
.block-of {
backgroundfont-size: rgba(34, 211, 238, 0.08)8em;
border-color: rgbavar(34, 211, 238, 0.12--text-dim);
}
.status-item {
 
/* Bracket annotations */
.bracket-group {
position: absolute;
display: flex;
align-items: center;
pointer-eventsgap: none6px;
}
.status-dot {
 
width: 7px; height: 7px;
/* Connector lines */
border-radius: 50%;
.connectors {
positionflex-shrink: absolute0;
inset: 0;
pointer-events: none;
}
.status-dot.ok { background: var(--text); }
.status-dot.warn { background: var(--text-muted); }
.status-dot.fail { border: 2px solid var(--text); background: transparent; }
 
/* ---- Side panel ---- */
.side-panel {
display: flex;
flex-direction: column;
gap: 20px16px;
}
 
.info-card {
background: var(--surface);
border: 1px solid var(--border);
border-radiusbackground: 14pxvar(--bg);
padding: 24px16px 18px;
transition: all 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}
 
.info-card .card-label {
font-familysize: 'IBM Plex Mono', monospace0.7em;
font-sizeweight: 10pxbold;
letter-spacing: 2px0.08em;
text-transform: uppercase;
color: var(--text-muted);
margin-bottom: 14px;
}
 
.info-card h3 {
font-family: 'DM Serif Display', serif;
font-size: 22px;
font-weight: 400;
margin-bottom: 10px;
line-height: 1.3;
transition: color 0.3s ease;
}
 
/* ---- Gauge ---- */
.info-card p {
.gauge-card { text-align: center; padding: 18px; }
font-size: 13.5px;
line-height: 1.7;
color: var(--text-dim);
font-weight: 300;
}
 
.infogauge-card .formulavalue {
marginfont-topsize: 14px2em;
font-weight: bold;
background: rgba(34, 211, 238, 0.06);
color: var(--text);
border: 1px solid rgba(34, 211, 238, 0.12);
borderline-radiusheight: 8px1.1;
padding: 12px 16px;
font-family: 'IBM Plex Mono', monospace;
font-size: 12px;
color: var(--accent-cyan);
letter-spacing: 0.3px;
}
.gauge-label {
 
font-size: 0.78em;
/* Solvency ratio gauge */
color: var(--text-muted);
.gauge-card {
textmargin-aligntop: center2px;
padding: 28px 24px;
}
.gauge-bar-track {
 
margin-top: 14px;
.gauge-wrapper {
positionheight: relative6px;
widthbackground: 160pxvar(--surface2);
heightborder-radius: 90px3px;
margin: 0 auto 16px;
overflow: hidden;
}
.gauge-bar-fill {
 
height: 100%;
.gauge-bg, .gauge-fill {
positionborder-radius: absolute3px;
widthbackground: 160pxvar(--text);
heighttransition: 160pxwidth 0.6s ease;
border-radius: 50%;
border: 14px solid transparent;
}
 
.gauge-bg {
border-top-color: var(--border);
border-left-color: var(--border);
border-right-color: var(--border);
transform: rotate(0deg);
}
 
.gauge-fill {
border-top-color: var(--accent-emerald);
border-left-color: var(--accent-emerald);
border-right-color: transparent;
transform: rotate(0deg);
transition: transform 1.2s cubic-bezier(0.22, 1, 0.36, 1);
}
 
.gauge-value {
font-family: 'IBM Plex Mono', monospace;
font-size: 28px;
font-weight: 600;
color: var(--accent-emerald);
margin-bottom: 4px;
}
 
.gauge-label {
font-size: 12px;
color: var(--text-muted);
font-weight: 500;
}
 
.gauge-thresholds {
display: flex;
justify-content: space-between;
margin-top: 12px6px;
paddingfont-size: 0 4px.68em;
}
 
.gauge-thresholds span {
font-family: 'IBM Plex Mono', monospace;
font-size: 10px;
color: var(--text-muted);
}
 
/* Slider---- controlsSliders ---- */
.slider-group { margin-bottom: 14px; }
.controls-card {
padding: 24px;
}
 
.slider-group {
margin-bottom: 18px;
}
 
.slider-group:last-child { margin-bottom: 0; }
 
.slider-header {
display: flex;
justify-content: space-between;
align-items: centerbaseline;
margin-bottom: 8px5px;
}
 
.slider-header label {
font-size: 120.5px8em;
font-weight: 500;
color: var(--text-dim);
}
.slider-val {
 
font-size: 0.8em;
.slider-header .slider-val {
font-familyweight: 'IBM Plex Mono', monospacebold;
font-sizecolor: 12pxvar(--text);
font-weightvariant-numeric: 500tabular-nums;
}
 
Line 444 ⟶ 296:
-webkit-appearance: none;
width: 100%;
height: 4px3px;
background: var(--surface2);
border-radius: 2px;
background: var(--border);
outline: none;
cursor: pointer;
}
 
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 16px14px; height: 14px;
height: 16px;
border-radius: 50%;
background: var(--accent-cyantext);
box-shadow: 0 0 10px rgba(34, 211, 238, 0.4);
cursor: pointer;
transitionborder: transform2px 0.15ssolid ease#fff;
box-shadow: 0 0 0 1px var(--border);
}
input[type="range"]::-moz-range-thumb {
 
width: 14px; height: 14px;
input[type="range"]::-webkit-slider-thumb:hover {
transformborder-radius: scale(1.2)50%;
background: var(--text);
}
 
/* Legend items below chart */
.legend-strip {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 24px;
}
 
.legend-item {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 10px;
background: rgba(255,255,255,0.03);
border: 1px solid var(--border);
border-radius: 6px;
font-size: 11px;
color: var(--text-dim);
cursor: pointer;
transitionborder: all2px 0.2ssolid ease#fff;
box-shadow: 0 0 0 1px var(--border);
}
 
/* ---- Detail card ---- */
.legend-item:hover {
.info-card h3 {
background: rgba(255,255,255,0.06);
font-size: 1.05em;
font-weight: bold;
color: var(--text);
margin-bottom: 6px;
line-height: 1.3;
}
.info-card p {
 
font-size: 0.84em;
.legend-dot {
widthcolor: 8pxvar(--text-dim);
line-height: 8px1.6;
border-radius: 2px;
flex-shrink: 0;
}
.formula {
 
margin-top: 10px;
/* Bracket annotations on liabilities side */
padding: 8px 12px;
.bracket-area {
positionbackground: relativevar(--surface);
border: 1px solid var(--surface2);
}
font-family: "Nimbus Roman No9 L", "Times New Roman", Times, serif;
 
font-size: 0.88em;
.bracket-label {
position: absolute;
right: -28px;
writing-mode: vertical-rl;
text-orientation: mixed;
font-family: 'IBM Plex Mono', monospace;
font-size: 10px;
letter-spacing: 1.5px;
text-transform: uppercase;
color: var(--text-muted);
opacity: 0.6;
}
 
/* Animations */
@keyframes fadeUp {
from { opacity: 0; transform: translateY(16px); }
to { opacity: 1; transform: translateY(0); }
}
 
@keyframes slideIn {
from { opacity: 0; transform: translateX(-8px); }
to { opacity: 1; transform: translateX(0); }
}
 
.bs-block {
animation: slideIn 0.5s ease-out both;
}
 
.bs-col:first-child .bs-block:nth-child(1) { animation-delay: 0.2s; }
.bs-col:last-child .bs-block:nth-child(1) { animation-delay: 0.3s; }
.bs-col:last-child .bs-block:nth-child(2) { animation-delay: 0.4s; }
.bs-col:last-child .bs-block:nth-child(3) { animation-delay: 0.5s; }
.bs-col:last-child .bs-block:nth-child(4) { animation-delay: 0.6s; }
 
/* Tooltip */
.tooltip {
position: fixed;
background: #1e293b;
border: 1px solid var(--border);
border-radius: 8px;
padding: 10px 14px;
font-size: 12px;
color: var(--text);
pointerletter-eventsspacing: none0.01em;
opacity: 0;
transition: opacity 0.2s ease;
max-width: 220px;
z-index: 100;
box-shadow: 0 8px 32px rgba(0,0,0,0.4);
}
 
/* ---- MCR badge inside SCR ---- */
.tooltip.show { opacity: 1; }
 
/* Grouped brackets */
.group-bracket {
position: absolute;
display: flex;
align-items: center;
pointer-events: none;
z-index: 3;
}
 
.group-bracket .bracket-line {
width: 2px;
background: currentColor;
border-radius: 1px;
opacity: 0.4;
}
 
.group-bracket .bracket-text {
font-family: 'IBM Plex Mono', monospace;
font-size: 10px;
letter-spacing: 1px;
text-transform: uppercase;
writing-mode: vertical-rl;
text-orientation: mixed;
padding: 0 6px;
opacity: 0.5;
}
 
/* Flow arrow between assets and liab */
.flow-arrow {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
color: var(--text-muted);
font-size: 10px;
font-family: 'IBM Plex Mono', monospace;
}
 
.flow-arrow svg {
opacity: 0.3;
}
 
/* Small badge */
.tier-badge {
display: inline-block;
padding: 2px1px 7px6px;
border-radius: 4px2px;
font-familysize: 'IBM Plex Mono', monospace0.72em;
font-sizeweight: 9pxbold;
fontmargin-weighttop: 6003px;
letter-spacingbackground: rgba(255,255,255,0.5px18);
margin-topcolor: 4pxinherit;
cursor: pointer;
}
.block-scr .tier-badge { background: rgba(0,0,0,0.08); }
 
/* ---- Deficit block ---- */
.tier-1 { background: rgba(52, 211, 153, 0.15); color: var(--accent-emerald); }
.block-deficit {
.tier-2 { background: rgba(251, 191, 36, 0.15); color: var(--accent-amber); }
.tier-3 { background: rgba(251, 113, 133, 0.15)#fff; color: var(--accent-rose); }
border: 2px dashed var(--text);
 
color: var(--text);
/* Status bar */
.status-bar {
display: flex;
gap: 24px;
justify-content: center;
margin-top: 16px;
flex-wrap: wrap;
}
 
/* ---- Print ---- */
.status-item {
@media print {
display: flex;
align.side-itemspanel { display: centernone; }
.main-grid { grid-template-columns: 1fr; }
gap: 8px;
.container { padding: 0; }
}
.bs-visual { border: 1px solid #000; }
 
.status-dot {
width: 6px;
height: 6px;
border-radius: 50%;
}
 
.status-dot.green { background: var(--accent-emerald); box-shadow: 0 0 8px rgba(52,211,153,0.5); }
.status-dot.amber { background: var(--accent-amber); box-shadow: 0 0 8px rgba(251,191,36,0.5); }
.status-dot.red { background: var(--accent-rose); box-shadow: 0 0 8px rgba(251,113,133,0.5); }
 
.status-item span {
font-size: 11px;
color: var(--text-dim);
font-weight: 500;
}
</style>
Line 652 ⟶ 377:
<div class="container">
<header>
<div class="eyebrow">Insurance Regulation Framework</div>
<h1>Solvency II Balance Sheet</h1>
<p>An interactiveInteractive breakdown of the market-value balance sheet under the EU Solvency &nbsp;II Directive. Adjust the sliders and click any block to explore how assets, technical provisions, and capital requirements interconnect.</p>
</header>
 
<div class="main-grid">
<!-- Left: Balancecolumn: balance-sheet visualdiagram -->
<div>
<div class="bs-visual" id="bsVisual">
<div class="bs-title-row">
<span class="bs-col-label">Assets</span>
<span class="bs-col-label">Liabilities &amp; Own Funds</span>
</div>
<div class="bs-columns" id="bsColumns">
<!-- Assets column -->
<div class="bs-col" id="assetsCol"></div>
<!-div class="bs-separator"><div Separator --class="line"></div></div>
<div class="bs-separator">
<div class="line"></div>
</div>
<!-- Liabilities column -->
<div class="bs-col" id="liabCol"></div>
</div>
 
<div class="legend-strip" id="legend"></div>
</div>
 
<div class="status-bar" id="statusBar"></div>
</div>
 
<!-- Right column: Sidecontrols & panelinfo -->
<div class="side-panel">
<!-- Solvency ratio -->
<div class="info-card gauge-card">
<div class="card-label">Solvency Ratio</div>
<div class="gauge-value" id="ratioValue">&mdash;</div>
<div class="gauge-label">Eligible Own Funds / SCR</div>
<div class="gauge-bar-track"><div class="gauge-bar-fill" id="ratioBar"></div></div>
<div class="gauge-thresholds">
<span style="color:var(--accent-rose)">1000% min</span>
<span style="color:var(--accent-amber)">150100% min</span>
<span style="color:var(--accent-emerald)">200%+</span>
<span>300%</divspan>
<div style="margin-top:14px; height:6px; border-radius:3px; background:var(--border); overflow:hidden;">
<div id="ratioBar" style="height:100%; border-radius:3px; transition: width 0.8s ease, background 0.5s ease;"></div>
</div>
</div>
 
<!-- Adjust valuesSliders -->
<div class="info-card controls-card">
<div class="card-label">Adjust Values (&euro; bn)</div>
 
<div class="slider-group">
<div class="slider-header">
<label>Total Assets</label>
<span class="slider-val" id="valAssets" style="color:var(--assets-color)">150</span>
</div>
<input type="range" id="sliderAssets" min="80" max="250" value="150">
Line 714 ⟶ 430:
<div class="slider-header">
<label>Best Estimate Liabilities</label>
<span class="slider-val" id="valBEL" style="color:var(--bel-color)">85</span>
</div>
<input type="range" id="sliderBEL" min="30" max="180" value="85">
Line 722 ⟶ 438:
<div class="slider-header">
<label>Risk Margin</label>
<span class="slider-val" id="valRM" style="color:var(--rm-color)">8</span>
</div>
<input type="range" id="sliderRM" min="1" max="30" value="8">
Line 730 ⟶ 446:
<div class="slider-header">
<label>SCR</label>
<span class="slider-val" id="valSCR" style="color:var(--scr-color)">35</span>
</div>
<input type="range" id="sliderSCR" min="10" max="80" value="35">
Line 738 ⟶ 454:
<div class="slider-header">
<label>MCR (% of SCR)</label>
<span class="slider-val" id="valMCR" style="color:var(--accent-violet)">35%</span>
</div>
<input type="range" id="sliderMCR" min="20" max="50" value="35">
Line 747 ⟶ 463:
<div class="info-card" id="detailCard">
<div class="card-label">Component Detail</div>
<h3 id="detailTitle">Hover overSelect a blockcomponent</h3>
<p id="detailDesc">Click or hover on any componentblock in the balance sheet to see its definition, purpose, and how it connectsrelationship to other elements.</p>
<div class="formula" id="detailFormula" style="display:none;"></div>
</div>
Line 754 ⟶ 470:
</div>
</div>
 
<div class="tooltip" id="tooltip"></div>
 
<script>
const data = { assets: 150, bel: 85, rm: 8, scr: 35, mcrPct: 35 };
assets: 150,
bel: 85,
rm: 8,
scr: 35,
mcrPct: 35
};
 
const descriptions = {
Line 775 ⟶ 483:
title: 'Best Estimate Liabilities (BEL)',
desc: 'The probability-weighted average of future cash flows for insurance obligations, discounted using the relevant risk-free interest rate term structure prescribed by EIOPA. It represents the expected cost of meeting policyholder obligations.',
formula: 'BEL = Σ\u03A3 PV(expected future cash flows)'
},
rm: {
title: 'Risk Margin',
desc: 'An additional amount over the BEL to ensure technical provisions are sufficient. Calculated as the cost of holding eligible own funds equal to the SCR over the lifetime of the obligations, using a prescribed cost-of-capital rate (currently 6%).',
formula: 'RM = CoC ×\u00D7 Σ\u03A3 SCR(t) / (1 + r(t))^t'
},
tp: {
title: 'Technical Provisions (TP)',
desc: 'The total value of insurance liabilities \u2014 the sum of the Best Estimate Liabilities and the Risk Margin. This represents the full amount the insurer must reserve to meet policyholder obligations.',
formula: 'TP = BEL + Risk Margin'
},
Line 790 ⟶ 498:
title: 'Solvency Capital Requirement',
desc: 'The capital buffer required to absorb significant unforeseen losses over a 1-year period with a 99.5% confidence level (i.e. a 1-in-200 year event). Can be calculated via the Standard Formula or an approved Internal Model.',
formula: 'SCR = VaR₉₉VaR\u2089\u2089.\u2085%(Basic Own Funds) over 1 year'
},
mcr: {
title: 'Minimum Capital Requirement',
desc: 'The minimum level of security below which the amount of financial resources should not fall. Breach triggers ultimate supervisory intervention \u2014 the insurer\'su2019s licenselicence may be withdrawn. Bounded between 25%–45\u201345% of SCR.',
formula: 'MCR = max(25% ×\u00D7 SCR, min(45% ×\u00D7 SCR, linear MCR))'
},
surplus: {
title: 'Free Surplus',
desc: 'Own funds in excess of the SCR \u2014 the capital cushion above regulatory requirements. A healthy surplus signals strong financial resilience and may support dividend distributions or growth strategies.',
formula: 'Surplus = Own Funds \u2212 SCR'
},
ownfunds: {
title: 'Eligible Own Funds',
desc: 'Total own funds available to cover the SCR and MCR. Classified into Tier 1 (highest quality \u2014 equity, retained earnings), Tier 2 (subordinated debt), and Tier 3 (limited eligibility). Tiering limits apply when covering SCR/MCR.',
formula: 'Own Funds = Assets \u2212 Technical Provisions'
}
};
 
const legendItems = [
{ id: 'assets', label: 'Assets', color: 'var(--assets-colorfill)' },
{ id: 'bel', label: 'BEL', color: 'var(--bel-colorfill)' },
{ id: 'rm', label: 'Risk Margin', color: 'var(--rm-colorfill)' },
{ id: 'scr', label: 'SCR', color: 'var(--scr-colorfill)' },
{ id: 'mcrsurplus', label: 'MCRSurplus', color: 'var(--accentsurplus-violetfill)' },
{ id: 'surplustp', label: 'SurplusTech. Prov.', color: 'var(--surplus-color)#72777d' },
{ id: 'ownfunds', label: 'Own Funds', color: '#c8ccd1' },
];
 
Line 831 ⟶ 540:
const total = data.assets;
const totalLiab = tp + data.scr + Math.max(0, surplus);
 
// Height proportions (use asset total as reference)
const ref = Math.max(total, totalLiab, 1);
const totalH = 480;
const pxPer = totalH / ref;
 
// Assets column
const assetsColac = document.getElementById('assetsCol');
assetsColac.innerHTML = '';
ac.appendChild(makeBlock('assets', 'block-assets', 'Total Assets', 'Market value', '\u20AC' + data.assets + 'bn', totalH));
 
// Liabilities
const assetBlock = makeBlock('assets', 'block-assets', 'Total Assets', `Market value`, `€${data.assets}bn`, totalH);
const lc = document.getElementById('liabCol');
assetsCol.appendChild(assetBlock);
lc.innerHTML = '';
 
// Liabilities column
const liabCol = document.getElementById('liabCol');
liabCol.innerHTML = '';
 
// BEL
const belH = Math.max(32, data.bel * pxPer);
liabCollc.appendChild(makeBlock('bel', 'block-bel', 'Best Estimate Liabilities', 'Discounted expected cash flows', `€${'\u20AC' + data.bel} + 'bn`', belH));
 
const rmH = Math.max(26, data.rm * pxPer);
// Risk Margin
lc.appendChild(makeBlock('rm', 'block-rm', 'Risk Margin', 'Cost-of-capital provision', '\u20AC' + data.rm + 'bn', rmH));
const rmH = Math.max(28, data.rm * pxPer);
liabCol.appendChild(makeBlock('rm', 'block-rm', 'Risk Margin', 'Cost-of-capital provision', `€${data.rm}bn`, rmH));
 
// SCR (show MCR within)
const scrH = Math.max(40, data.scr * pxPer);
const scrBlock = makeBlock('scr', 'block-scr', 'SCR', `'Solvency Capital Req.`', `€${'\u20AC' + data.scr} + 'bn`', scrH);
// MCR badge inside SCR
const mcrBadge = document.createElement('div');
mcrBadge.className = 'tier-badge tier-3';
mcrBadge.textContent = `'MCR €${\u20AC' + mcr} + 'bn`';
mcrBadge.style.position = 'relative';
mcrBadge.style.cursor = 'pointer';
mcrBadge.dataset.block = 'mcr';
mcrBadge.addEventListener('click', function(e) { e.stopPropagation(); showDetail('mcr'); });
scrBlock.appendChild(mcrBadge);
liabCollc.appendChild(scrBlock);
 
// Surplus
if (surplus > 0) {
const surpH = Math.max(2826, surplus * pxPer);
liabCollc.appendChild(makeBlock('surplus', 'block-surplus', 'Free Surplus', 'Excess own funds', `€${'\u20AC' + surplus} + 'bn`', surpH));
} else if (ownFunds < data.scr) {
const defBlock = makeBlock('surplus', 'block-deficit', 'Capital Shortfall', 'Own funds < SCR', '\u20AC' + Math.round(data.scr - ownFunds) + 'bn deficit', 32);
const deficitH = 32;
lc.appendChild(defBlock);
const defBlock = makeBlock('surplus', 'block-scr', 'Capital Shortfall', 'Own funds < SCR', `€${Math.round(data.scr - ownFunds)}bn deficit`, deficitH);
defBlock.style.border = '1px dashed var(--accent-rose)';
liabCol.appendChild(defBlock);
}
 
// Ratio bar
constvar rVal = document.getElementById('ratioValue');
constvar rBar = document.getElementById('ratioBar');
rVal.textContent = `${Math.round(ratio)} + '%`';
const barWrBar.style.width = Math.min(100, ratio / 3) + '%';
rBar.style.widthopacity = barWratio +< 100 ? '0.35' : '%1';
if (ratio >= 150) {
rVal.style.color = 'var(--accent-emerald)';
rBar.style.background = 'var(--accent-emerald)';
} else if (ratio >= 100) {
rVal.style.color = 'var(--accent-amber)';
rBar.style.background = 'var(--accent-amber)';
} else {
rVal.style.color = 'var(--accent-rose)';
rBar.style.background = 'var(--accent-rose)';
}
 
// Status bar
constvar sb = document.getElementById('statusBar');
constvar scrStatusscrOk = ownFunds >= data.scr;
constvar mcrStatusmcrOk = ownFunds >= mcr;
sb.innerHTML = `
'<div class="status-item"><div class="status-dot ' + (scrOk ? 'ok' : 'fail') + '"></div><span>SCR ' + (scrOk ? 'covered' : 'breached') + '</span></div>' +
<div class="status-item">
'<div class="status-item"><div class="status-dot ${scrStatus' + (mcrOk ? 'greenok' : 'redfail') + '}"></div><span>MCR ' + (mcrOk ? 'covered' : 'breached') + '</span></div>' +
'<div class="status-item"><div class="status-dot ' + (ratio >= 150 ? 'ok' : ratio >= 100 ? 'warn' : 'fail') + '"></div><span>Ratio: ' + Math.round(ratio) + '%</span></div>' +
<span>SCR ${scrStatus ? 'Covered' : 'Breached'}</span>
'<div class="status-item" style="cursor:pointer" onclick="showDetail(\'ownfunds\')"><span style="font-weight:bold">Own Funds: \u20AC' + Math.round(ownFunds) + 'bn</span></div>';
</div>
<div class="status-item">
<div class="status-dot ${mcrStatus ? 'green' : 'red'}"></div>
<span>MCR ${mcrStatus ? 'Covered' : 'Breached'}</span>
</div>
<div class="status-item">
<div class="status-dot ${ratio >= 150 ? 'green' : ratio >= 100 ? 'amber' : 'red'}"></div>
<span>Ratio: ${Math.round(ratio)}%</span>
</div>
<div class="status-item" style="cursor:pointer;" onclick="showDetail('ownfunds')">
<div class="status-dot" style="background:var(--accent-cyan);box-shadow:0 0 8px rgba(34,211,238,0.5);"></div>
<span>Own Funds: €${Math.round(ownFunds)}bn</span>
</div>
`;
 
// Legend
constvar legendlg = document.getElementById('legend');
legendlg.innerHTML = '';
legendItems.forEach(function(l =>) {
constvar liel = document.createElement('div');
liel.className = 'legend-item';
liel.innerHTML = `'<span class="legend-dot" style="background:${' + l.color} + '"></span>${' + l.label}`;
liel.onclick = function() =>{ showDetail(l.id); };
legendlg.appendChild(liel);
});
// Add TP and Own Funds to legend
[{ id: 'tp', label: 'Tech. Provisions', color: 'var(--tp-color)' },
{ id: 'ownfunds', label: 'Own Funds', color: 'var(--own-funds-color)' }
].forEach(l => {
const li = document.createElement('div');
li.className = 'legend-item';
li.innerHTML = `<span class="legend-dot" style="background:${l.color}"></span>${l.label}`;
li.onclick = () => showDetail(l.id);
legend.appendChild(li);
});
}
 
function makeBlock(id, cls, label, sublabel, value, height) {
constvar el = document.createElement('div');
el.className = `'bs-block ${' + cls}`;
el.style.height = height + 'px';
el.dataset.block = id;
el.innerHTML = `
'<div class="label">${' + label} + '</div>' +
${(height > 4038 ? `'<div class="sublabel">${' + sublabel} + '</div>`' : ''}) +
'<div class="value">${' + value} + '</div>';
el.addEventListener('mouseenter', function() { showDetail(id); });
`;
el.addEventListener('mouseenterclick', function() =>{ showDetail(id); });
el.addEventListener('click', () => showDetail(id));
return el;
}
 
function showDetail(id) {
constvar info = descriptions[id];
if (!info) return;
document.getElementById('detailTitle').textContent = info.title;
document.getElementById('detailDesc').textContent = info.desc;
constvar fEl = document.getElementById('detailFormula');
if (info.formula) { fEl.style.display = 'block'; fEl.textContent = info.formula; }
else { fEl.style.display = 'blocknone'; }
document.querySelectorAll('.bs-block').forEach(function(b) { b.classList.remove('active'); });
fEl.textContent = info.formula;
document.querySelectorAll('.bs-block[data-block="' + id + '"]').forEach(function(b) { b.classList.add('active'); });
} else {
fEl.style.display = 'none';
}
 
// Highlight active block
document.querySelectorAll('.bs-block').forEach(b => b.classList.remove('active'));
document.querySelectorAll(`.bs-block[data-block="${id}"]`).forEach(b => b.classList.add('active'));
}
 
function bindSlider(sid, vid, key, suffix) {
// Slider bindings
var s = document.getElementById(sid);
function bindSlider(sliderId, valId, key, suffix = '') {
constvar sliderv = document.getElementById(sliderIdvid);
s.addEventListener('input', function() {
const valEl = document.getElementById(valId);
data[key] = parseInt(s.value);
slider.addEventListener('input', () => {
const v.textContent = parseInt(slidersuffix ? s.value + suffix : s.value);
data[key] = v;
valEl.textContent = suffix ? v + suffix : v;
render();
});
}
 
bindSlider('sliderAssets', 'valAssets', 'assets', '');
bindSlider('sliderBEL', 'valBEL', 'bel', '');
bindSlider('sliderRM', 'valRM', 'rm', '');
bindSlider('sliderSCR', 'valSCR', 'scr', '');
bindSlider('sliderMCR', 'valMCR', 'mcrPct', '%');
 
// Initial render
render();
</script>