eq performance

This commit is contained in:
samantha42
2026-06-02 00:16:03 +02:00
parent f2cf27c76f
commit 9b8d624be9
5 changed files with 185 additions and 6 deletions
+160
View File
@@ -0,0 +1,160 @@
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=IBM+Plex+Sans:wght@300;400;500&display=swap');
.eq-wrap { font-family: 'IBM Plex Sans', monospace; padding: 2rem 0 1rem; }
.eq-header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 0.25rem; }
.eq-title { font-family: 'IBM Plex Mono', monospace; font-size: 11px; font-weight: 500; letter-spacing: 0.12em; color: var(--color-text-secondary); text-transform: uppercase; }
.eq-ytd { font-family: 'IBM Plex Mono', monospace; font-size: 22px; font-weight: 500; color: var(--color-text-primary); margin: 0.1rem 0 1.5rem; }
.eq-ytd span { font-size: 13px; font-weight: 400; color: #1D9E75; margin-left: 8px; }
.eq-divider { border: none; border-top: 0.5px solid var(--color-border-tertiary); margin-bottom: 1.5rem; }
.eq-legend { display: flex; gap: 20px; margin-bottom: 0.75rem; font-size: 12px; font-family: 'IBM Plex Mono', monospace; color: var(--color-text-secondary); align-items: center; }
.eq-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 1.5rem; }
.eq-stat { background: var(--color-background-secondary); border-radius: var(--border-radius-md); padding: 0.75rem 1rem; }
.eq-stat-label { font-size: 11px; font-family: 'IBM Plex Mono', monospace; color: var(--color-text-secondary); letter-spacing: 0.05em; margin-bottom: 4px; }
.eq-stat-val { font-size: 16px; font-weight: 500; font-family: 'IBM Plex Mono', monospace; }
.eq-stat-val.pos { color: #1D9E75; }
.eq-stat-val.neg { color: #E24B4A; }
.eq-note { font-size: 11px; color: var(--color-text-secondary); margin-top: 1rem; font-family: 'IBM Plex Mono', monospace; }
</style>
<div class="eq-wrap">
<p class="eq-title">Equity · Portfolio Performance</p>
<div class="eq-header">
<div class="eq-ytd">+9.58% <span>YTD</span></div>
<span style="font-size:11px; font-family:'IBM Plex Mono',monospace; color:var(--color-text-secondary);">2026</span>
</div>
<hr class="eq-divider">
<div class="eq-legend">
<span style="display:flex;align-items:center;gap:6px;">
<span style="width:16px;height:2px;background:#1D9E75;border-radius:1px;display:inline-block;"></span>cumulative
</span>
<span style="display:flex;align-items:center;gap:6px;">
<span style="width:16px;height:10px;background:rgba(29,158,117,0.25);border:1px solid #1D9E75;border-radius:2px;display:inline-block;"></span>monthly
</span>
</div>
<div style="position:relative; width:100%; height:220px;">
<canvas id="eqChart" role="img" aria-label="Line chart of cumulative and monthly equity returns. Cumulative YTD is plus 9.58%.">
Monthly: Jan +8.13%, Feb 8.84%, Mar +0.41%, Apr +6.59%, May +3.20%, Now +0.64%. Cumulative: Jan +8.13%, Feb 1.43%, Mar 1.02%, Apr +5.51%, May +8.89%, Now +9.58%.
</canvas>
</div>
<div class="eq-stats">
<div class="eq-stat">
<div class="eq-stat-label">best month</div>
<div class="eq-stat-val pos">+8.13%</div>
</div>
<div class="eq-stat">
<div class="eq-stat-label">worst month</div>
<div class="eq-stat-val neg">8.84%</div>
</div>
<div class="eq-stat">
<div class="eq-stat-label">cumulative YTD</div>
<div class="eq-stat-val pos">+9.58%</div>
</div>
</div>
<p class="eq-note">// data through Jun 2026 · monthly returns & cumulative</p>
</div>
<script>
(function() {
const monthly = [8.13, -8.84, 0.41, 6.59, 3.20, 0.64];
const cumul = [8.13, -1.43, -1.02, 5.51, 8.89, 9.58];
const labels = ['jan','feb','mar','apr','may','now'];
function initChart() {
const isDark = matchMedia('(prefers-color-scheme: dark)').matches;
const gridColor = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)';
const textColor = isDark ? 'rgba(255,255,255,0.45)' : 'rgba(0,0,0,0.45)';
const zeroColor = isDark ? 'rgba(255,255,255,0.2)' : 'rgba(0,0,0,0.15)';
new Chart(document.getElementById('eqChart'), {
type: 'bar',
data: {
labels,
datasets: [
{
type: 'line',
label: 'cumulative',
data: cumul,
borderColor: '#1D9E75',
borderWidth: 2,
pointBackgroundColor: '#1D9E75',
pointRadius: 4,
pointHoverRadius: 6,
tension: 0.35,
fill: { target: 'origin', above: 'rgba(29,158,117,0.08)', below: 'rgba(226,75,74,0.08)' },
yAxisID: 'y',
order: 1
},
{
type: 'bar',
label: 'monthly',
data: monthly,
backgroundColor: monthly.map(v => v >= 0 ? 'rgba(29,158,117,0.25)' : 'rgba(226,75,74,0.25)'),
borderColor: monthly.map(v => v >= 0 ? '#1D9E75' : '#E24B4A'),
borderWidth: 1,
borderRadius: 3,
yAxisID: 'y',
order: 2
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: { mode: 'index', intersect: false },
plugins: {
legend: { display: false },
tooltip: {
backgroundColor: isDark ? '#2C2C2A' : '#fff',
borderColor: isDark ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.1)',
borderWidth: 1,
titleColor: textColor,
bodyColor: isDark ? 'rgba(255,255,255,0.8)' : 'rgba(0,0,0,0.8)',
titleFont: { family: "'IBM Plex Mono', monospace", size: 11 },
bodyFont: { family: "'IBM Plex Mono', monospace", size: 12 },
padding: 10,
callbacks: {
label: ctx => {
const sign = ctx.parsed.y >= 0 ? '+' : '';
return ` ${ctx.dataset.label}: ${sign}${ctx.parsed.y.toFixed(2)}%`;
}
}
}
},
scales: {
x: {
grid: { display: false },
border: { display: false },
ticks: { color: textColor, font: { family: "'IBM Plex Mono', monospace", size: 11 }, autoSkip: false }
},
y: {
grid: {
color: ctx => ctx.tick.value === 0 ? zeroColor : gridColor,
lineWidth: ctx => ctx.tick.value === 0 ? 1 : 0.5
},
border: { display: false },
ticks: {
color: textColor,
font: { family: "'IBM Plex Mono', monospace", size: 11 },
callback: v => (v >= 0 ? '+' : '') + v.toFixed(1) + '%'
}
}
}
}
});
}
if (typeof Chart !== 'undefined') {
initChart();
} else {
var s = document.createElement('script');
s.src = 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js';
s.onload = initChart;
document.head.appendChild(s);
}
})();
</script>
+12 -1
View File
@@ -249,6 +249,17 @@
<a class="outlink" href="/static/pdf/novo.pdf" target="_blank">Read file</a>
</div>
<br>
<div class="section-head">
<h2>Equity portfolio performance</h2>
</div>
<div class="exp-card">
<div hx-get="/static/components/eq.html" hx-trigger="load" hx-swap="outerHTML">
<span class="spinner">Loading chart...</span>
</div>
</div>
</section>
<section id="newsletter">
<div class="page-header">
@@ -436,7 +447,7 @@
<div class="footer-copy">© 2026 — all rights reserved</div>
</footer>
<div id="login-overlay" style="min-width: 50%; position: fixed; inset: 0; z-index: 100; display: none; align-items: center; justify-content: center; background: rgba(0,0,0,0.35); backdrop-filter: blur(12px);">
<div hx-get="login" hx-trigger="load" hx-swap="outerHTML">
<div hx-get="/login" hx-trigger="load" hx-swap="outerHTML">
<span class="spinner">Loading login page...</span>
</div>
</div>